<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Overall looks very nice. Some comments below. (I have tried to make them easier to find by prepending them with >>).</div><div class=""><br class=""></div><div class="">Some general comments.</div><div class="">- Need distinct tests for iOS and macosx.</div><div class="">- Need to make sure that unavailability of the APIs are diagnosed. We do this with existing APIs.</div><div class="">  (We either need to error on older deployment targets—which in at least one case </div><div class="">   means < OS X 10.10—or implement entrypoints in libarclite. )</div><div class="">- Sema tests need be expanded for issuing diagnostics for every new added error or warning.</div><div class="">- __has_feature test need be added.</div><div class="">- Fariborz</div><div class=""><br class=""></div><div class="">diff --git a/docs/ObjectiveCLiterals.rst b/docs/ObjectiveCLiterals.rst</div><div class="">index 8907c1e..a223fba 100644</div><div class="">--- a/docs/ObjectiveCLiterals.rst</div><div class="">+++ b/docs/ObjectiveCLiterals.rst</div><div class="">@@ -119,8 +119,8 @@ Objective-C provides a new syntax for boxing C expressions:</div><div class=""> </div><div class="">     @( <expression> )</div><div class=""> </div><div class="">-Expressions of scalar (numeric, enumerated, BOOL) and C string pointer</div><div class="">-types are supported:</div><div class="">+Expressions of scalar (numeric, enumerated, BOOL), C string pointer</div><div class="">+and NSValue constructible types are supported:</div><div class=""> </div><div class=""> .. code-block:: objc</div><div class=""> </div><div class="">@@ -136,6 +136,18 @@ types are supported:</div><div class="">     NSString *path = @(getenv("PATH"));       // [NSString stringWithUTF8String:(getenv("PATH"))]</div><div class="">     NSArray *pathComponents = [path componentsSeparatedByString:@":"];</div><div class=""> </div><div class="">+    // NS structs</div><div class="">+    NSValue *center = @(view.center);         // [NSValue valueWithPoint:view.center]</div><div class="">+    NSValue *frame = @(view.frame);           // [NSValue valueWithRect:view.frame]</div><div class="">+</div><div class="">+    // Pointers</div><div class="">+    NSValue *memObject = @( malloc(42) );     // [NSValue valueWithPointer:malloc(42)]</div><div class="">+</div><div class="">+    // Objective-C objects</div><div class="">+    id obj = [NSObject new];</div><div class="">+    NSValue *nonretainedObject = @(obj);      // [NSValue valueWithNonretainedObject:obj]</div><div class="">+    NSValue *nonretainedString = @(@"Hello"); // [NSValue valueWithNonretainedObject:@"Hello"]</div><div class="">+</div><div class=""> Boxed Enums</div><div class=""> -----------</div><div class=""> </div><div class="">@@ -218,6 +230,28 @@ character data is valid. Passing ``NULL`` as the character pointer will</div><div class=""> raise an exception at runtime. When possible, the compiler will reject</div><div class=""> ``NULL`` character pointers used in boxed expressions.</div><div class=""> </div><div class="">+Boxed C Strucutres, pointers and NSObjects</div><div class="">+------------------</div><div class="">+</div><div class="">+Boxed expressions support construction of NSValue objects.</div><div class="">+It said that some C structures, pointers and NSObjects can be used:</div><div class="">+</div><div class="">+.. code-block:: objc</div><div class="">+</div><div class="">+    NSPoint p;</div><div class="">+    NSValue *point = @(p);          // valueWithPoint:</div><div class="">+    NSSize s;</div><div class="">+    NSValue *size = @(s);           // valueWithSize:</div><div class="">+    const void *p = malloc(42);</div><div class="">+    NSValue *memory = @(p);         // valueWithPointer:</div><div class="">+    id obj = [NSObject new];</div><div class="">+    NSValue *nonretained = @(obj);  // valueWithNonretainedObject:</div><div class="">+</div><div class="">+The following list of structs supported, depends on target system:</div><div class="">+</div><div class="">+  - OSX: ``NSPoint``, ``NSSize``, ``NSRect``, ``NSRange``</div><div class="">+  - iOS: ``CGPoint``, ``CGSize``, ``CGRect``, ``NSRange``</div><div class=""><br class=""></div><div class="">>> Have you considered NSEdgeInsets? With this API:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; font-family: Menlo;" class="">@interface NSValue (NSValueGeometryExtensions)</div></div><div style="margin: 0px; font-size: 11px; font-family: Menlo;" class="">…</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;" class=""><div style="margin: 0px;" class="">+ (NSValue *)valueWithEdgeInsets:(NSEdgeInsets)insets __attribute__((availability(macosx,introduced=10.10)));</div><div style="margin: 0px;" class="">…</div><div style="margin: 0px;" class=""><br class=""></div></div><div class="">+</div><div class=""> Container Literals</div><div class=""> ==================</div><div class=""> </div><div class="">diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h</div><div class="">index 817c0cc..f296e8f 100644</div><div class="">--- a/include/clang/AST/ExprObjC.h</div><div class="">+++ b/include/clang/AST/ExprObjC.h</div><div class="">@@ -124,6 +124,15 @@ public:</div><div class="">   </div><div class="">   // Iterators</div><div class="">   child_range children() { return child_range(&SubExpr, &SubExpr+1); }</div><div class="">+</div><div class="">+  typedef ConstExprIterator const_arg_iterator;</div><div class="">+</div><div class="">+  const_arg_iterator arg_begin() const {</div><div class="">+    return reinterpret_cast<Stmt const * const*>(&SubExpr);</div><div class="">+  }</div><div class="">+  const_arg_iterator arg_end() const {</div><div class="">+    return reinterpret_cast<Stmt const * const*>(&SubExpr + 1);</div><div class="">+  }</div><div class="">   </div><div class="">   friend class ASTStmtReader;</div><div class=""> };</div><div class="">diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h</div><div class="">index 33fcce2..97654b5 100644</div><div class="">--- a/include/clang/AST/NSAPI.h</div><div class="">+++ b/include/clang/AST/NSAPI.h</div><div class="">@@ -33,9 +33,10 @@ public:</div><div class="">     ClassId_NSMutableArray,</div><div class="">     ClassId_NSDictionary,</div><div class="">     ClassId_NSMutableDictionary,</div><div class="">-    ClassId_NSNumber</div><div class="">+    ClassId_NSNumber,</div><div class="">+    ClassId_NSValue</div><div class="">   };</div><div class="">-  static const unsigned NumClassIds = 7;</div><div class="">+  static const unsigned NumClassIds = 8;</div><div class=""> </div><div class="">   enum NSStringMethodKind {</div><div class="">     NSStr_stringWithString,</div><div class="">@@ -158,12 +159,29 @@ public:</div><div class="">   };</div><div class="">   static const unsigned NumNSNumberLiteralMethods = 15;</div><div class=""> </div><div class="">+  /// \brief Enumerates the NSValue methods used to generate literals.</div><div class="">+  enum NSValueLiteralMethodKind {</div><div class="">+    NSValueWithPoint,</div><div class="">+    NSValueWithSize,</div><div class="">+    NSValueWithRect,</div><div class="">+    NSValueWithCGPoint,</div><div class="">+    NSValueWithCGSize,</div><div class="">+    NSValueWithCGRect,</div><div class="">+    NSValueWithRange,</div><div class="">+    NSValueWithPointer,</div><div class="">+    NSValueWithNonretainedObject</div><div class="">+  };</div><div class="">+  static const unsigned NumNSValueLiteralMethods = 9;</div><div class="">+</div><div class="">   /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.</div><div class="">   /// \param Instance if true it will return the selector for the init* method</div><div class="">   /// otherwise it will return the selector for the number* method.</div><div class="">   Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,</div><div class="">                                       bool Instance) const;</div><div class=""> </div><div class="">+  /// \brief The Objective-C NSValue selectors used to create NSValue literals.</div><div class="">+  Selector getNSValueLiteralSelector(NSValueLiteralMethodKind MK) const;</div><div class="">+</div><div class="">   bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,</div><div class="">                                  Selector Sel) const {</div><div class="">     return Sel == getNSNumberLiteralSelector(MK, false) ||</div><div class="">@@ -179,12 +197,31 @@ public:</div><div class="">   Optional<NSNumberLiteralMethodKind></div><div class="">       getNSNumberFactoryMethodKind(QualType T) const;</div><div class=""> </div><div class="">+  /// \brief Determine the appropriate NSValue factory method kind for a</div><div class="">+  /// literal of the given type.</div><div class="">+  Optional<NSValueLiteralMethodKind></div><div class="">+      getNSValueFactoryMethodKind(QualType T) const;</div><div class="">+</div><div class="">   /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.</div><div class="">   bool isObjCBOOLType(QualType T) const;</div><div class="">   /// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.</div><div class="">   bool isObjCNSIntegerType(QualType T) const;</div><div class="">   /// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.</div><div class="">   bool isObjCNSUIntegerType(QualType T) const;</div><div class="">+  /// \brief Returns true if \param T is a typedef of "NSPoint" in objective-c.</div><div class="">+  bool isObjCNSPointType(QualType T) const;</div><div class="">+  /// \brief Returns true if \param T is a typedef of "NSSize" in objective-c.</div><div class="">+  bool isObjCNSSizeType(QualType T) const;</div><div class="">+  /// \brief Returns true if \param T is a typedef of "NSRect" in objective-c.</div><div class="">+  bool isObjCNSRectType(QualType T) const;</div><div class="">+  /// \brief Returns true if \param T is a typedef of "CGPoint" in objective-c.</div><div class="">+  bool isObjCCGPointType(QualType T) const;</div><div class="">+  /// \brief Returns true if \param T is a typedef of "CGSize" in objective-c.</div><div class="">+  bool isObjCCGSizeType(QualType T) const;</div><div class="">+  /// \brief Returns true if \param T is a typedef of "CGRect" in objective-c.</div><div class="">+  bool isObjCCGRectType(QualType T) const;</div><div class="">+  /// \brief Returns true if \param T is a typedef of "NSRange" in objective-c.</div><div class="">+  bool isObjCNSRangeType(QualType T) const;</div><div class="">   /// \brief Returns one of NSIntegral typedef names if \param T is a typedef</div><div class="">   /// of that name in objective-c.</div><div class="">   StringRef GetNSIntegralKind(QualType T) const;</div><div class="">@@ -211,12 +248,18 @@ private:</div><div class="">   mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];</div><div class="">   mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];</div><div class=""> </div><div class="">+  /// \brief The Objective-C NSValue selectors used to create NSValue literals.</div><div class="">+  mutable Selector NSValueClassSelectors[NumNSValueLiteralMethods];</div><div class="">+</div><div class="">   mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel,</div><div class="">                    setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel,</div><div class="">                    isEqualSel;</div><div class=""> </div><div class="">   mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;</div><div class="">   mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId;</div><div class="">+  mutable IdentifierInfo *NSPointId, *NSSizeId, *NSRectId;</div><div class="">+  mutable IdentifierInfo *CGPointId, *CGSizeId, *CGRectId;</div><div class="">+  mutable IdentifierInfo *NSRangeId;</div><div class=""> };</div><div class=""> </div><div class=""> }  // end namespace clang</div><div class="">diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td</div><div class="">index 28ac96d..515fd63 100644</div><div class="">--- a/include/clang/Basic/DiagnosticSemaKinds.td</div><div class="">+++ b/include/clang/Basic/DiagnosticSemaKinds.td</div><div class="">@@ -2042,6 +2042,8 @@ def err_attr_objc_ownership_redundant : Error<</div><div class="">   "the type %0 is already explicitly ownership-qualified">;</div><div class=""> def err_undeclared_nsnumber : Error<</div><div class="">   "NSNumber must be available to use Objective-C literals">;</div><div class="">+def err_undeclared_nsvalue : Error<</div><div class="">+  "NSValue must be available to use Objective-C boxed expressions”>;</div><div class=""> def err_invalid_nsnumber_type : Error<</div><div class="">   "%0 is not a valid literal type for NSNumber">;</div><div class=""> def err_undeclared_nsstring : Error<</div><div class="">diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h</div><div class="">index 02aa984..dbf6cd4 100644</div><div class="">--- a/include/clang/Sema/Sema.h</div><div class="">+++ b/include/clang/Sema/Sema.h</div><div class="">@@ -660,12 +660,21 @@ public:</div><div class="">   /// \brief The declaration of the Objective-C NSNumber class.</div><div class="">   ObjCInterfaceDecl *NSNumberDecl;</div><div class=""> </div><div class="">+  /// \brief The declaration of the Objective-C NSValue class.</div><div class="">+  ObjCInterfaceDecl *NSValueDecl;</div><div class="">+</div><div class="">   /// \brief Pointer to NSNumber type (NSNumber *).</div><div class="">   QualType NSNumberPointer;</div><div class=""> </div><div class="">+  /// \brief Pointer to NSValue type (NSValue *).</div><div class="">+  QualType NSValuePointer;</div><div class="">+</div><div class="">   /// \brief The Objective-C NSNumber methods used to create NSNumber literals.</div><div class="">   ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods];</div><div class=""> </div><div class="">+  /// \brief The Objective-C NSValue methods used to create NSValue literals.</div><div class="">+  ObjCMethodDecl *NSValueLiteralMethods[NSAPI::NumNSValueLiteralMethods];</div><div class="">+</div><div class="">   /// \brief The declaration of the Objective-C NSString class.</div><div class="">   ObjCInterfaceDecl *NSStringDecl;</div><div class=""> </div><div class="">diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp</div><div class="">index 3dc750a..3b5b1b2 100644</div><div class="">--- a/lib/AST/NSAPI.cpp</div><div class="">+++ b/lib/AST/NSAPI.cpp</div><div class="">@@ -17,7 +17,9 @@ using namespace clang;</div><div class=""> NSAPI::NSAPI(ASTContext &ctx)</div><div class="">   : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),</div><div class="">     NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),</div><div class="">-    NSUTF8StringEncodingId(nullptr) {}</div><div class="">+    NSUTF8StringEncodingId(nullptr), NSPointId(nullptr),</div><div class="">+    NSSizeId(nullptr), NSRectId(nullptr), CGPointId(nullptr),</div><div class="">+    CGSizeId(nullptr), CGRectId(nullptr), NSRangeId(nullptr) {}</div><div class=""> </div><div class=""> IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {</div><div class="">   static const char *ClassName[NumClassIds] = {</div><div class="">@@ -27,7 +29,8 @@ IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {</div><div class="">     "NSMutableArray",</div><div class="">     "NSDictionary",</div><div class="">     "NSMutableDictionary",</div><div class="">-    "NSNumber"</div><div class="">+    "NSNumber",</div><div class="">+    "NSValue"</div><div class="">   };</div><div class=""> </div><div class="">   if (!ClassIds[K])</div><div class="">@@ -279,6 +282,25 @@ Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,</div><div class="">   return Sels[MK];</div><div class=""> }</div><div class=""> </div><div class="">+Selector NSAPI::getNSValueLiteralSelector(NSValueLiteralMethodKind MK) const {</div><div class="">+  static const char *ClassSelectorName[NumNSValueLiteralMethods] = {</div><div class="">+    "valueWithPoint",</div><div class="">+    "valueWithSize",</div><div class="">+    "valueWithRect",</div><div class="">+    "valueWithCGPoint",</div><div class="">+    "valueWithCGSize",</div><div class="">+    "valueWithCGRect",</div><div class="">+    "valueWithRange",</div><div class="">+    "valueWithPointer",</div><div class="">+    "valueWithNonretainedObject"</div><div class="">+  };</div><div class="">+</div><div class="">+  if (NSValueClassSelectors[MK].isNull())</div><div class="">+    NSValueClassSelectors[MK] =</div><div class="">+      Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(ClassSelectorName[MK]));</div><div class="">+  return NSValueClassSelectors[MK];</div><div class="">+}</div><div class="">+</div><div class=""> Optional<NSAPI::NSNumberLiteralMethodKind></div><div class=""> NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {</div><div class="">   for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {</div><div class="">@@ -371,6 +393,34 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {</div><div class="">   return None;</div><div class=""> }</div><div class=""> </div><div class="">+Optional<NSAPI::NSValueLiteralMethodKind></div><div class="">+NSAPI::getNSValueFactoryMethodKind(QualType T) const {</div><div class="">+  const RecordType *RT = T->getAsStructureType();</div><div class="">+  if (RT) {</div><div class="">+    if (isObjCNSPointType(T))</div><div class="">+      return NSAPI::NSValueWithPoint;</div><div class="">+    if (isObjCNSSizeType(T))</div><div class="">+      return NSAPI::NSValueWithSize;</div><div class="">+    if (isObjCNSRectType(T))</div><div class="">+      return NSAPI::NSValueWithRect;</div><div class="">+    if (isObjCCGPointType(T))</div><div class="">+      return NSAPI::NSValueWithCGPoint;</div><div class="">+    if (isObjCCGSizeType(T))</div><div class="">+      return NSAPI::NSValueWithCGSize;</div><div class="">+    if (isObjCCGRectType(T))</div><div class="">+      return NSAPI::NSValueWithCGRect;</div><div class="">+    if (isObjCNSRangeType(T))</div><div class="">+      return NSAPI::NSValueWithRange;</div><div class=""><br class=""></div><div class="">>> Better to return None; here instead of falling though with unnecessary extra checks. It is also more verbose as to the intention.</div><div class=""><br class=""></div><div class="">+  }</div><div class="">+</div><div class="">+  if (T->isVoidPointerType())</div><div class="">+    return NSAPI::NSValueWithPointer;</div><div class="">+  if (T->isObjCObjectPointerType())</div><div class=""><br class=""></div><div class="">>> You are intentionally using this API instead of T-><span style="font-family: Menlo; font-size: 11px;" class="">isObjCIdType(), right? If so, please add comment.</span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class=""><br class=""></span></div><div class="">+    return NSAPI::NSValueWithNonretainedObject;</div><div class="">+</div><div class="">+  return None;</div><div class="">+}</div><div class="">+</div><div class=""> /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.</div><div class=""> bool NSAPI::isObjCBOOLType(QualType T) const {</div><div class="">   return isObjCTypedef(T, "BOOL", BOOLId);</div><div class="">@@ -384,6 +434,41 @@ bool NSAPI::isObjCNSUIntegerType(QualType T) const {</div><div class="">   return isObjCTypedef(T, "NSUInteger", NSUIntegerId);</div><div class=""> }</div><div class=""> </div><div class="">+/// \brief Returns true if \param T is a typedef of "NSPoint" in objective-c.</div><div class="">+bool NSAPI::isObjCNSPointType(QualType T) const {</div><div class="">+  return isObjCTypedef(T, "NSPoint", NSPointId);</div><div class="">+}</div><div class="">+</div><div class="">+/// \brief Returns true if \param T is a typedef of "NSSize" in objective-c.</div><div class="">+bool NSAPI::isObjCNSSizeType(QualType T) const {</div><div class="">+  return isObjCTypedef(T, "NSSize", NSSizeId);</div><div class="">+}</div><div class="">+</div><div class="">+/// \brief Returns true if \param T is a typedef of "NSRect" in objective-c.</div><div class="">+bool NSAPI::isObjCNSRectType(QualType T) const {</div><div class="">+  return isObjCTypedef(T, "NSRect", NSRectId);</div><div class="">+}</div><div class="">+</div><div class="">+/// \brief Returns true if \param T is a typedef of "CGPoint" in objective-c.</div><div class="">+bool NSAPI::isObjCCGPointType(QualType T) const {</div><div class="">+  return isObjCTypedef(T, "CGPoint", CGPointId);</div><div class="">+}</div><div class="">+</div><div class="">+/// \brief Returns true if \param T is a typedef of "CGSize" in objective-c.</div><div class="">+bool NSAPI::isObjCCGSizeType(QualType T) const {</div><div class="">+  return isObjCTypedef(T, "CGSize", CGSizeId);</div><div class="">+}</div><div class="">+</div><div class="">+/// \brief Returns true if \param T is a typedef of "CGRect" in objective-c.</div><div class="">+bool NSAPI::isObjCCGRectType(QualType T) const {</div><div class="">+  return isObjCTypedef(T, "CGRect", CGRectId);</div><div class="">+}</div><div class="">+</div><div class="">+/// \brief Returns true if \param T is a typedef of "NSRange" in objective-c.</div><div class="">+bool NSAPI::isObjCNSRangeType(QualType T) const {</div><div class="">+  return isObjCTypedef(T, "NSRange", NSRangeId);</div><div class="">+}</div><div class="">+</div><div class=""> StringRef NSAPI::GetNSIntegralKind(QualType T) const {</div><div class="">   if (!Ctx.getLangOpts().ObjC1 || T.isNull())</div><div class="">     return StringRef();</div><div class="">diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp</div><div class="">index ca67c4b..d2975b8 100644</div><div class="">--- a/lib/CodeGen/CGObjC.cpp</div><div class="">+++ b/lib/CodeGen/CGObjC.cpp</div><div class="">@@ -55,12 +55,12 @@ llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E)</div><div class=""> </div><div class=""> /// EmitObjCBoxedExpr - This routine generates code to call</div><div class=""> /// the appropriate expression boxing method. This will either be</div><div class="">-/// one of +[NSNumber numberWith<Type>:], or +[NSString stringWithUTF8String:].</div><div class="">+/// one of +[NSNumber numberWith<Type>:], or +[NSString stringWithUTF8String:],</div><div class="">+/// or [NSValue valueWith<Type>:].</div><div class=""> ///</div><div class=""> llvm::Value *</div><div class=""> CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) {</div><div class="">   // Generate the correct selector for this literal's concrete type.</div><div class="">-  const Expr *SubExpr = E->getSubExpr();</div><div class="">   // Get the method.</div><div class="">   const ObjCMethodDecl *BoxingMethod = E->getBoxingMethod();</div><div class="">   assert(BoxingMethod && "BoxingMethod is null");</div><div class="">@@ -73,12 +73,9 @@ CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) {</div><div class="">   CGObjCRuntime &Runtime = CGM.getObjCRuntime();</div><div class="">   const ObjCInterfaceDecl *ClassDecl = BoxingMethod->getClassInterface();</div><div class="">   llvm::Value *Receiver = Runtime.GetClass(*this, ClassDecl);</div><div class="">-  </div><div class="">-  const ParmVarDecl *argDecl = *BoxingMethod->param_begin();</div><div class="">-  QualType ArgQT = argDecl->getType().getUnqualifiedType();</div><div class="">-  RValue RV = EmitAnyExpr(SubExpr);</div><div class="">+</div><div class="">   CallArgList Args;</div><div class="">-  Args.add(RV, ArgQT);</div><div class="">+  EmitCallArgs(Args, BoxingMethod, E->arg_begin(), E->arg_end());</div><div class=""><br class=""></div><div class="">>> Isn’t this something you can check-in before the overall patch can be checked in?</div><div class=""> </div><div class="">   RValue result = Runtime.GenerateMessageSend(</div><div class="">       *this, ReturnValueSlot(), BoxingMethod->getReturnType(), Sel, Receiver,</div><div class="">diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp</div><div class="">index b402a93..a17052f 100644</div><div class="">--- a/lib/Lex/PPMacroExpansion.cpp</div><div class="">+++ b/lib/Lex/PPMacroExpansion.cpp</div><div class="">@@ -911,6 +911,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {</div><div class="">       .Case("objc_array_literals", LangOpts.ObjC2)</div><div class="">       .Case("objc_dictionary_literals", LangOpts.ObjC2)</div><div class="">       .Case("objc_boxed_expressions", LangOpts.ObjC2)</div><div class="">+      .Case("objc_boxed_nsvalue_expressions", LangOpts.ObjC2)</div><div class=""><br class=""></div><div class="">>> Presumable the new __has_feature need be documented somewhere.</div><div class="">>> Also, why can’t place this under the umbrella objc_boxed_expressions?</div><div class=""><br class=""></div><div class="">       .Case("arc_cf_code_audited", true)</div><div class="">       // C11 features</div><div class="">       .Case("c_alignas", LangOpts.C11)</div><div class="">diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp</div><div class="">index eeee352..2d3fa5b 100644</div><div class="">--- a/lib/Sema/SemaExprObjC.cpp</div><div class="">+++ b/lib/Sema/SemaExprObjC.cpp</div><div class="">@@ -255,6 +255,86 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc,</div><div class="">   return Method;</div><div class=""> }</div><div class=""> </div><div class="">+/// \brief Retrieve the NSValue factory method that should be used to create</div><div class="">+/// an Objective-C literal for the given type.</div><div class="">+static ObjCMethodDecl *getNSValueFactoryMethod(Sema &S, SourceLocation Loc,</div><div class="">+                                               QualType ValueType) {</div><div class="">+  Optional<NSAPI::NSValueLiteralMethodKind> Kind =</div><div class="">+  S.NSAPIObj->getNSValueFactoryMethodKind(ValueType);</div><div class="">+</div><div class="">+  if (!Kind) {</div><div class="">+    return nullptr;</div><div class="">+  }</div><div class="">+</div><div class="">+  // If we already looked up this method, we're done.</div><div class="">+  if (S.NSValueLiteralMethods[*Kind])</div><div class="">+    return S.NSValueLiteralMethods[*Kind];</div><div class="">+</div><div class="">+  Selector Sel = S.NSAPIObj->getNSValueLiteralSelector(*Kind);</div><div class="">+</div><div class="">+  ASTContext &CX = S.Context;</div><div class="">+</div><div class="">+  // Look up the NSValue class, if we haven't done so already. It's cached</div><div class="">+  // in the Sema instance.</div><div class="">+  if (!S.NSValueDecl) {</div><div class="">+    IdentifierInfo *NSValueId =</div><div class="">+    S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSValue);</div><div class="">+    NamedDecl *IF = S.LookupSingleName(S.TUScope, NSValueId,</div><div class="">+                                       Loc, Sema::LookupOrdinaryName);</div><div class="">+    S.NSValueDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);</div><div class="">+    if (!S.NSValueDecl) {</div><div class="">+      if (S.getLangOpts().DebuggerObjCLiteral) {</div><div class="">+        // Create a stub definition of NSValue.</div><div class="">+        S.NSValueDecl = ObjCInterfaceDecl::Create(CX,</div><div class="">+                                                  CX.getTranslationUnitDecl(),</div><div class="">+                                                  SourceLocation(), NSValueId,</div><div class="">+                                                  nullptr, SourceLocation());</div><div class="">+      } else {</div><div class="">+        // Otherwise, require a declaration of NSValue.</div><div class="">+        S.Diag(Loc, diag::err_undeclared_nsvalue);</div><div class="">+        return nullptr;</div><div class="">+      }</div><div class="">+    } else if (!S.NSValueDecl->hasDefinition()) {</div><div class="">+      S.Diag(Loc, diag::err_undeclared_nsvalue);</div><div class=""><br class=""></div><div class="">>> Maybe we should have a clearer diagnostic here.</div><div class=""><br class=""></div><div class="">+      return nullptr;</div><div class="">+    }</div><div class="">+</div><div class="">+    // generate the pointer to NSValue type.</div><div class="">+    QualType NSValueObject = CX.getObjCInterfaceType(S.NSValueDecl);</div><div class="">+    S.NSValuePointer = CX.getObjCObjectPointerType(NSValueObject);</div><div class="">+  }</div><div class="">+</div><div class="">+  // Look for the appropriate method within NSValue.</div><div class="">+  ObjCMethodDecl *Method = S.NSValueDecl->lookupClassMethod(Sel);</div><div class="">+  if (!Method && S.getLangOpts().DebuggerObjCLiteral) {</div><div class="">+    // create a stub definition this NSValue factory method.</div><div class="">+    TypeSourceInfo *ReturnTInfo = nullptr;</div><div class="">+    Method =</div><div class="">+    ObjCMethodDecl::Create(CX, SourceLocation(), SourceLocation(), Sel,</div><div class="">+                           S.NSValuePointer, ReturnTInfo, S.NSValueDecl,</div><div class="">+                           /*isInstance=*/false, /*isVariadic=*/false,</div><div class="">+                           /*isPropertyAccessor=*/false,</div><div class="">+                           /*isImplicitlyDeclared=*/true,</div><div class="">+                           /*isDefined=*/false, ObjCMethodDecl::Required,</div><div class="">+                           /*HasRelatedResultType=*/false);</div><div class="">+    ParmVarDecl *value = ParmVarDecl::Create(S.Context, Method,</div><div class="">+                                             SourceLocation(), SourceLocation(),</div><div class="">+                                             &CX.Idents.get("value"),</div><div class="">+                                             ValueType, /*TInfo=*/nullptr,</div><div class="">+                                             SC_None, nullptr);</div><div class="">+    Method->setMethodParams(S.Context, value, None);</div><div class="">+  }</div><div class="">+</div><div class="">+  if (!validateBoxingMethod(S, Loc, S.NSValueDecl, Sel, Method))</div><div class="">+    return nullptr;</div><div class="">+</div><div class="">+  // Note: if the parameter type is out-of-line, we'll catch it later in the</div><div class="">+  // implicit conversion.</div><div class="">+</div><div class="">+  S.NSValueLiteralMethods[*Kind] = Method;</div><div class="">+  return Method;</div><div class="">+}</div><div class="">+</div><div class=""> /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the</div><div class=""> /// numeric literal expression. Type of the expression will be "NSNumber *”.</div><div class=""><br class=""></div><div class="">>> Comment need be updated.</div><div class=""><br class=""></div><div class=""> ExprResult Sema::BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number) {</div><div class="">@@ -456,10 +536,55 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {</div><div class="">   }</div><div class="">   ValueExpr = RValue.get();</div><div class="">   QualType ValueType(ValueExpr->getType());</div><div class="">-  if (const PointerType *PT = ValueType->getAs<PointerType>()) {</div><div class="">-    QualType PointeeType = PT->getPointeeType();</div><div class="">-    if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {</div><div class="">+  if (ValueType->isBuiltinType() || ValueType->isEnumeralType()) {</div><div class=""><br class=""></div><div class="">>> You are adding an extra check for isEnumeralType() beyond the original source. Please add</div><div class="">>> comment for it and add test to back up the comment.</div><div class=""><br class=""></div><div class="">+    // We support numeric, char and BOOL/bool types.</div><div class="">+    // Check for a top-level character literal.</div><div class="">+    if (const CharacterLiteral *Char =</div><div class="">+        dyn_cast<CharacterLiteral>(ValueExpr->IgnoreParens())) {</div><div class="">+      // In C, character literals have type 'int'. That's not the type we want</div><div class="">+      // to use to determine the Objective-c literal kind.</div><div class="">+      switch (Char->getKind()) {</div><div class="">+      case CharacterLiteral::Ascii:</div><div class="">+        ValueType = Context.CharTy;</div><div class="">+        break;</div><div class=""> </div><div class="">+      case CharacterLiteral::Wide:</div><div class="">+        ValueType = Context.getWideCharType();</div><div class="">+        break;</div><div class="">+</div><div class="">+      case CharacterLiteral::UTF16:</div><div class="">+        ValueType = Context.Char16Ty;</div><div class="">+        break;</div><div class="">+</div><div class="">+      case CharacterLiteral::UTF32:</div><div class="">+        ValueType = Context.Char32Ty;</div><div class="">+        break;</div><div class="">+      }</div><div class="">+    }</div><div class="">+</div><div class="">+    if (const EnumType *ET = ValueType->getAs<EnumType>()) {</div><div class="">+      if (!ET->getDecl()->isComplete()) {</div><div class="">+        Diag(SR.getBegin(), diag::err_objc_incomplete_boxed_expression_type)</div><div class="">+        << ValueType << ValueExpr->getSourceRange();</div><div class="">+        return ExprError();</div><div class="">+      }</div><div class="">+</div><div class="">+      ValueType = ET->getDecl()->getIntegerType();</div><div class="">+    }</div><div class="">+</div><div class="">+    CheckForIntOverflow(ValueExpr);</div><div class="">+    // FIXME:  Do I need to do anything special with BoolTy expressions?</div><div class="">+</div><div class="">+    // Look for the appropriate method within NSNumber.</div><div class="">+    BoxingMethod = getNSNumberFactoryMethod(*this, SR.getBegin(), ValueType);</div><div class="">+    BoxedType = NSNumberPointer;</div><div class="">+</div><div class="">+  } else if (ValueType->isStructureType() || ValueType->isPointerType() || ValueType->isObjCObjectPointerType()) {</div><div class="">+    // Support of NSValue and NSString construction</div><div class="">+</div><div class="">+    // Check if we can construct NSString from chars</div><div class="">+    const PointerType *PT = ValueType->getAs<PointerType>();</div><div class="">+    if (PT && Context.hasSameUnqualifiedType(PT->getPointeeType(), Context.CharTy)) {</div><div class="">       if (!NSStringDecl) {</div><div class="">         IdentifierInfo *NSStringId =</div><div class="">           NSAPIObj->getNSClassId(NSAPI::ClassId_NSString);</div><div class="">@@ -486,7 +611,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {</div><div class="">         QualType NSStringObject = Context.getObjCInterfaceType(NSStringDecl);</div><div class="">         NSStringPointer = Context.getObjCObjectPointerType(NSStringObject);</div><div class="">       }</div><div class="">-      </div><div class="">+</div><div class=""><br class=""></div><div class="">>> Please remove these diffs</div><div class=""><br class=""></div><div class="">       if (!StringWithUTF8StringMethod) {</div><div class="">         IdentifierInfo *II = &Context.Idents.get("stringWithUTF8String");</div><div class="">         Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);</div><div class="">@@ -518,60 +643,22 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {</div><div class=""> </div><div class="">         if (!validateBoxingMethod(*this, SR.getBegin(), NSStringDecl,</div><div class="">                                   stringWithUTF8String, BoxingMethod))</div><div class="">-           return ExprError();</div><div class="">+          return ExprError();</div><div class=""> >> Please remove these diffs</div><div class=""><br class=""></div><div class="">         StringWithUTF8StringMethod = BoxingMethod;</div><div class="">       }</div><div class="">-      </div><div class="">+</div><div class="">>> Please remove these diffs</div><div class=""><br class=""></div><div class="">       BoxingMethod = StringWithUTF8StringMethod;</div><div class="">       BoxedType = NSStringPointer;</div><div class="">-    }</div><div class="">-  } else if (ValueType->isBuiltinType()) {</div><div class="">-    // The other types we support are numeric, char and BOOL/bool. We could also</div><div class="">-    // provide limited support for structure types, such as NSRange, NSRect, and</div><div class="">-    // NSSize. See NSValue (NSValueGeometryExtensions) in <Foundation/NSGeometry.h></div><div class="">-    // for more details.</div><div class="">-</div><div class="">-    // Check for a top-level character literal.</div><div class="">-    if (const CharacterLiteral *Char =</div><div class="">-        dyn_cast<CharacterLiteral>(ValueExpr->IgnoreParens())) {</div><div class="">-      // In C, character literals have type 'int'. That's not the type we want</div><div class="">-      // to use to determine the Objective-c literal kind.</div><div class="">-      switch (Char->getKind()) {</div><div class="">-      case CharacterLiteral::Ascii:</div><div class="">-        ValueType = Context.CharTy;</div><div class="">-        break;</div><div class="">-        </div><div class="">-      case CharacterLiteral::Wide:</div><div class="">-        ValueType = Context.getWideCharType();</div><div class="">-        break;</div><div class="">-        </div><div class="">-      case CharacterLiteral::UTF16:</div><div class="">-        ValueType = Context.Char16Ty;</div><div class="">-        break;</div><div class="">-        </div><div class="">-      case CharacterLiteral::UTF32:</div><div class="">-        ValueType = Context.Char32Ty;</div><div class="">-        break;</div><div class="">-      }</div><div class="">-    }</div><div class="">-    CheckForIntOverflow(ValueExpr);</div><div class="">-    // FIXME:  Do I need to do anything special with BoolTy expressions?</div><div class="">-    </div><div class="">-    // Look for the appropriate method within NSNumber.</div><div class="">-    BoxingMethod = getNSNumberFactoryMethod(*this, SR.getBegin(), ValueType);</div><div class="">-    BoxedType = NSNumberPointer;</div><div class="">+    } else {</div><div class="">+      // Support for +valueWithNonretaintedObject and +valueWithPointer.</div><div class="">+      // Limited support for structure types, such as NSRange,</div><div class="">+      // NS/CG Rect, Size and Point.</div><div class=""> </div><div class="">-  } else if (const EnumType *ET = ValueType->getAs<EnumType>()) {</div><div class="">-    if (!ET->getDecl()->isComplete()) {</div><div class="">-      Diag(SR.getBegin(), diag::err_objc_incomplete_boxed_expression_type)</div><div class="">-        << ValueType << ValueExpr->getSourceRange();</div><div class="">-      return ExprError();</div><div class="">+      // Look for the appropriate method within NSValue.</div><div class="">+      BoxingMethod = getNSValueFactoryMethod(*this, SR.getBegin(), ValueType);</div><div class="">+      BoxedType = NSValuePointer;</div><div class="">     }</div><div class="">-</div><div class="">-    BoxingMethod = getNSNumberFactoryMethod(*this, SR.getBegin(),</div><div class="">-                                            ET->getDecl()->getIntegerType());</div><div class="">-    BoxedType = NSNumberPointer;</div><div class="">   }</div><div class=""> </div><div class="">   if (!BoxingMethod) {</div><div class="">diff --git a/test/CodeGenObjC/Inputs/nsvalue-boxed-expressions-support.h b/test/CodeGenObjC/Inputs/nsvalue-boxed-expressions-support.h</div><div class="">new file mode 100644</div><div class="">index 0000000..fe8a9a2</div><div class="">--- /dev/null</div><div class="">+++ b/test/CodeGenObjC/Inputs/nsvalue-boxed-expressions-support.h</div><div class="">@@ -0,0 +1,66 @@</div><div class="">+#ifndef OBJC_NSVALUE_LITERAL_SUPPORT_H</div><div class="">+#define OBJC_NSVALUE_LITERAL_SUPPORT_H</div><div class="">+</div><div class="">+typedef unsigned long NSUInteger;</div><div class="">+typedef double CGFloat;</div><div class="">+</div><div class="">+typedef struct _NSRange {</div><div class="">+    NSUInteger location;</div><div class="">+    NSUInteger length;</div><div class="">+} NSRange;</div><div class="">+</div><div class="">+// OS X Specific</div><div class="">+</div><div class="">+typedef struct _NSPoint {</div><div class="">+    CGFloat x;</div><div class="">+    CGFloat y;</div><div class="">+} NSPoint;</div><div class="">+</div><div class="">+typedef struct _NSSize {</div><div class="">+    CGFloat width;</div><div class="">+    CGFloat height;</div><div class="">+} NSSize;</div><div class="">+</div><div class="">+typedef struct _NSRect {</div><div class="">+    NSPoint origin;</div><div class="">+    NSSize size;</div><div class="">+} NSRect;</div><div class="">+</div><div class="">+// iOS Specific</div><div class="">+</div><div class="">+struct CGPoint {</div><div class="">+  CGFloat x;</div><div class="">+  CGFloat y;</div><div class="">+};</div><div class="">+typedef struct CGPoint CGPoint;</div><div class="">+</div><div class="">+struct CGSize {</div><div class="">+  CGFloat width;</div><div class="">+  CGFloat height;</div><div class="">+};</div><div class="">+typedef struct CGSize CGSize;</div><div class="">+</div><div class="">+struct CGRect {</div><div class="">+  CGPoint origin;</div><div class="">+  CGSize size;</div><div class="">+};</div><div class="">+typedef struct CGRect CGRect;</div><div class="">+</div><div class="">+@interface NSValue</div><div class="">++ (NSValue *)valueWithRange:(NSRange)range;</div><div class="">+</div><div class="">+// OS X Specific</div><div class="">++ (NSValue *)valueWithPoint:(NSPoint)point;</div><div class="">++ (NSValue *)valueWithSize:(NSSize)size;</div><div class="">++ (NSValue *)valueWithRect:(NSRect)rect;</div><div class="">+</div><div class=""><br class=""></div><div class="">>> It is better to add macosx availability attribute here.</div><div class=""><br class=""></div><div class="">+// iOS Specific</div><div class="">++ (NSValue *)valueWithCGPoint:(CGPoint)point;</div><div class="">++ (NSValue *)valueWithCGSize:(CGSize)size;</div><div class="">++ (NSValue *)valueWithCGRect:(CGRect)rect;</div><div class="">+</div><div class=""><br class=""></div><div class="">>> It is better to add iOS availability attribute here.</div><div class=""><br class=""></div><div class="">++ (NSValue *)valueWithPointer:(const void *)pointer;</div><div class="">++ (NSValue *)valueWithNonretainedObject:(id)object;</div><div class="">+@end</div><div class="">+</div><div class="">+#endif // OBJC_NSVALUE_LITERAL_SUPPORT_H</div><div class="">diff --git a/test/CodeGenObjC/nsvalue-boxed-expressions-arc.m b/test/CodeGenObjC/nsvalue-boxed-expressions-arc.m</div><div class="">new file mode 100644</div><div class="">index 0000000..9c30161</div><div class="">--- /dev/null</div><div class="">+++ b/test/CodeGenObjC/nsvalue-boxed-expressions-arc.m</div><div class="">@@ -0,0 +1,190 @@</div><div class="">+// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s</div><div class=""><br class=""></div><div class="">>> If you are not using ‘weak’ objects no need to provide -fobjc-runtime-has-weak </div><div class=""><br class=""></div><div class="">>> Need one for iOS with its own checks.</div><div class=""><br class=""></div><div class="">+</div><div class="">+#import "nsvalue-boxed-expressions-support.h"</div><div class="">+</div><div class="">+// CHECK:      [[CLASS:@.*]]        = external global %struct._class_t</div><div class="">+// CHECK:      [[NSVALUE:@.*]]      = {{.*}}[[CLASS]]{{.*}}</div><div class="">+</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithRange:{{.*}}</div><div class="">+// CHECK-NEXT: [[RANGE_SEL:@.*]]    = {{.*}}[[METH]]{{.*}}</div><div class="">+</div><div class="">+// OS X Specific</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithPoint:{{.*}}</div><div class="">+// CHECK-NEXT: [[POINT_SEL:@.*]]    = {{.*}}[[METH]]{{.*}}</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithSize:{{.*}}</div><div class="">+// CHECK-NEXT: [[SIZE_SEL:@.*]]     = {{.*}}[[METH]]{{.*}}</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithRect:{{.*}}</div><div class="">+// CHECK-NEXT: [[RECT_SEL:@.*]]     = {{.*}}[[METH]]{{.*}}</div><div class=""><br class=""></div><div class="">>> No. Please have two distinct runs and checks for iOS and macosx. </div><div class=""><br class=""></div><div class="">+</div><div class="">+// iOS Specfific</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithCGPoint:{{.*}}</div><div class="">+// CHECK-NEXT: [[CGPOINT_SEL:@.*]]  = {{.*}}[[METH]]{{.*}}</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithCGSize:{{.*}}</div><div class="">+// CHECK-NEXT: [[CGSIZE_SEL:@.*]]   = {{.*}}[[METH]]{{.*}}</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithCGRect:{{.*}}</div><div class="">+// CHECK-NEXT: [[CGRECT_SEL:@.*]]   = {{.*}}[[METH]]{{.*}}</div><div class="">+</div><div class=""><br class=""></div><div class="">>> No. Please have two distinct runs and checks for iOS and macosx. </div><div class=""><br class=""></div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithPointer:{{.*}}</div><div class="">+// CHECK-NEXT: [[POINTER_SEL:@.*]]  = {{.*}}[[METH]]{{.*}}</div><div class="">+</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithNonretainedObject:{{.*}}</div><div class="">+// CHECK-NEXT: [[NONRET_SEL:@.*]]   = {{.*}}[[METH]]{{.*}}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doRange()</div><div class="">+void doRange() {</div><div class="">+  // CHECK:      [[RANGE:%.*]]     = bitcast %struct._NSRange* {{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]]  = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]       = load i8** [[RANGE_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]      = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  // CHECK:      [[RANGE_PTR:%.*]] = bitcast %struct._NSRange* {{.*}}</div><div class="">+  // CHECK-NEXT: [[P1_PTR:%.*]]    = getelementptr {{.*}} [[RANGE_PTR]], i32 0, i32 0</div><div class="">+  // CHECK-NEXT: [[P1:%.*]]        = load i64* [[P1_PTR]], align 1</div><div class="">+  // CHECK-NEXT: [[P2_PTR:%.*]]    = getelementptr {{.*}} [[RANGE_PTR]], i32 0, i32 1</div><div class="">+  // CHECK-NEXT: [[P2:%.*]]        = load i64* [[P2_PTR]], align 1</div><div class="">+  NSRange ns_range = { .location = 0, .length = 42 };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i64 [[P1]], i64 [[P2]])</div><div class="">+  // CHECK:      call i8* @objc_retainAutoreleasedReturnValue</div><div class="">+  NSValue *range = @(ns_range);</div><div class="">+  // CHECK:      call void @objc_release</div><div class="">+  // CHECK-NEXT: ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doPoint()</div><div class="">+void doPoint() {</div><div class="">+  // CHECK:      [[POINT:%.*]]     = bitcast %struct._NSPoint* {{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]]  = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]       = load i8** [[POINT_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]      = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  // CHECK:      [[POINT_PTR:%.*]] = bitcast %struct._NSPoint* {{.*}}</div><div class="">+  // CHECK-NEXT: [[P1_PTR:%.*]]    = getelementptr {{.*}} [[POINT_PTR]], i32 0, i32 0</div><div class="">+  // CHECK-NEXT: [[P1:%.*]]        = load double* [[P1_PTR]], align 1</div><div class="">+  // CHECK-NEXT: [[P2_PTR:%.*]]    = getelementptr {{.*}} [[POINT_PTR]], i32 0, i32 1</div><div class="">+  // CHECK-NEXT: [[P2:%.*]]        = load double* [[P2_PTR]], align 1</div><div class="">+  NSPoint ns_point = { .x = 42, .y = 24 };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], double [[P1]], double [[P2]])</div><div class="">+  // CHECK:      call i8* @objc_retainAutoreleasedReturnValue</div><div class="">+  NSValue *point = @(ns_point);</div><div class="">+  // CHECK:      call void @objc_release</div><div class="">+  // CHECK-NEXT: ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doSize()</div><div class="">+void doSize() {</div><div class="">+  // CHECK:      [[SIZE:%.*]]     = bitcast %struct._NSSize* {{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[SIZE_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  // CHECK:      [[SIZE_PTR:%.*]] = bitcast %struct._NSSize* {{.*}}</div><div class="">+  // CHECK-NEXT: [[P1_PTR:%.*]]   = getelementptr {{.*}} [[SIZE_PTR]], i32 0, i32 0</div><div class="">+  // CHECK-NEXT: [[P1:%.*]]       = load double* [[P1_PTR]], align 1</div><div class="">+  // CHECK-NEXT: [[P2_PTR:%.*]]   = getelementptr {{.*}} [[SIZE_PTR]], i32 0, i32 1</div><div class="">+  // CHECK-NEXT: [[P2:%.*]]       = load double* [[P2_PTR]], align 1</div><div class="">+  NSSize ns_size = { .width = 42, .height = 24 };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], double [[P1]], double [[P2]])</div><div class="">+  // CHECK:      call i8* @objc_retainAutoreleasedReturnValue</div><div class="">+  NSValue *size = @(ns_size);</div><div class="">+  // CHECK:      call void @objc_release</div><div class="">+  // CHECK-NEXT: ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doRect()</div><div class="">+void doRect() {</div><div class="">+  // CHECK:      [[RECT:%.*]]     = alloca %struct._NSRect{{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[RECT_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  NSPoint ns_point = { .x = 42, .y = 24 };</div><div class="">+  NSSize ns_size = { .width = 42, .height = 24 };</div><div class="">+  NSRect ns_rect = { .origin = ns_point, .size = ns_size };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], %struct._NSRect* byval align 8 [[RECT]])</div><div class="">+  // CHECK:      call i8* @objc_retainAutoreleasedReturnValue</div><div class="">+  NSValue *rect = @(ns_rect);</div><div class="">+  // CHECK:      call void @objc_release</div><div class="">+  // CHECK-NEXT: ret void</div><div class="">+}</div><div class="">+</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doCGPoint()</div><div class="">+void doCGPoint() {</div><div class="">+  // CHECK:      [[POINT:%.*]]     = bitcast %struct.CGPoint* {{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]]  = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]       = load i8** [[CGPOINT_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]      = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  // CHECK:      [[POINT_PTR:%.*]] = bitcast %struct.CGPoint* {{.*}}</div><div class="">+  // CHECK-NEXT: [[P1_PTR:%.*]]    = getelementptr {{.*}} [[POINT_PTR]], i32 0, i32 0</div><div class="">+  // CHECK-NEXT: [[P1:%.*]]        = load double* [[P1_PTR]], align 1</div><div class="">+  // CHECK-NEXT: [[P2_PTR:%.*]]    = getelementptr {{.*}} [[POINT_PTR]], i32 0, i32 1</div><div class="">+  // CHECK-NEXT: [[P2:%.*]]        = load double* [[P2_PTR]], align 1</div><div class="">+  CGPoint cg_point = { .x = 42, .y = 24 };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], double [[P1]], double [[P2]])</div><div class="">+  // CHECK:      call i8* @objc_retainAutoreleasedReturnValue</div><div class="">+  NSValue *point = @(cg_point);</div><div class="">+  // CHECK:      call void @objc_release</div><div class="">+  // CHECK-NEXT: ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doCGSize()</div><div class="">+void doCGSize() {</div><div class="">+  // CHECK:      [[SIZE:%.*]]     = bitcast %struct.CGSize* {{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[CGSIZE_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  // CHECK:      [[SIZE_PTR:%.*]] = bitcast %struct.CGSize* {{.*}}</div><div class="">+  // CHECK-NEXT: [[P1_PTR:%.*]]   = getelementptr {{.*}} [[SIZE_PTR]], i32 0, i32 0</div><div class="">+  // CHECK-NEXT: [[P1:%.*]]       = load double* [[P1_PTR]], align 1</div><div class="">+  // CHECK-NEXT: [[P2_PTR:%.*]]   = getelementptr {{.*}} [[SIZE_PTR]], i32 0, i32 1</div><div class="">+  // CHECK-NEXT: [[P2:%.*]]       = load double* [[P2_PTR]], align 1</div><div class="">+  CGSize cg_size = { .width = 42, .height = 24 };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], double [[P1]], double [[P2]])</div><div class="">+  // CHECK:      call i8* @objc_retainAutoreleasedReturnValue</div><div class="">+  NSValue *size = @(cg_size);</div><div class="">+  // CHECK:      call void @objc_release</div><div class="">+  // CHECK-NEXT: ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doCGRect()</div><div class="">+void doCGRect() {</div><div class="">+  // CHECK:      [[RECT:%.*]]     = alloca %struct.CGRect{{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[CGRECT_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  CGPoint cg_point = { .x = 42, .y = 24 };</div><div class="">+  CGSize cg_size = { .width = 42, .height = 24 };</div><div class="">+  CGRect cg_rect = { .origin = cg_point, .size = cg_size };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], %struct.CGRect* byval align 8 [[RECT]])</div><div class="">+  // CHECK:      call i8* @objc_retainAutoreleasedReturnValue</div><div class="">+  NSValue *rect = @(cg_rect);</div><div class="">+  // CHECK:      call void @objc_release</div><div class="">+  // CHECK-NEXT: ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doVoidPointer()</div><div class="">+void doVoidPointer() {</div><div class="">+  // CHECK:      [[POINTER:%.*]]  = alloca i8*{{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[PARAM:%.*]]    = load i8** [[POINTER]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[POINTER_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  const void *pointer = 0;</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM]])</div><div class="">+  // CHECK:      call i8* @objc_retainAutoreleasedReturnValue</div><div class="">+  NSValue *value = @(pointer);</div><div class="">+  // CHECK:      call void @objc_release</div><div class="">+  // CHECK-NEXT: ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doNonretainedObject()</div><div class="">+void doNonretainedObject() {</div><div class="">+  // CHECK:      [[OBJ:%.*]]      = alloca i8*{{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[PARAM:%.*]]    = load i8** [[OBJ]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[NONRET_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  id obj;</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM]])</div><div class="">+  // CHECK:      call i8* @objc_retainAutoreleasedReturnValue</div><div class="">+  NSValue *object = @(obj);</div><div class="">+  // CHECK:      call void @objc_release</div><div class="">+  // CHECK:      call void @objc_release</div><div class="">+  // CHECK-NEXT: ret void</div><div class="">+}</div><div class="">diff --git a/test/CodeGenObjC/nsvalue-boxed-expressions.m b/test/CodeGenObjC/nsvalue-boxed-expressions.m</div><div class="">new file mode 100644</div><div class="">index 0000000..c078fbe</div><div class="">--- /dev/null</div><div class="">+++ b/test/CodeGenObjC/nsvalue-boxed-expressions.m</div><div class="">@@ -0,0 +1,171 @@</div><div class="">+// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s</div><div class="">+</div><div class="">+#import "nsvalue-boxed-expressions-support.h"</div><div class="">+</div><div class="">+// CHECK:      [[CLASS:@.*]]        = external global %struct._class_t</div><div class="">+// CHECK:      [[NSVALUE:@.*]]      = {{.*}}[[CLASS]]{{.*}}</div><div class="">+</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithRange:{{.*}}</div><div class="">+// CHECK-NEXT: [[RANGE_SEL:@.*]]    = {{.*}}[[METH]]{{.*}}</div><div class="">+</div><div class="">+// OS X Specific</div><div class=""><br class=""></div><div class="">>> See comment above.</div><div class=""><br class=""></div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithPoint:{{.*}}</div><div class="">+// CHECK-NEXT: [[POINT_SEL:@.*]]    = {{.*}}[[METH]]{{.*}}</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithSize:{{.*}}</div><div class="">+// CHECK-NEXT: [[SIZE_SEL:@.*]]     = {{.*}}[[METH]]{{.*}}</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithRect:{{.*}}</div><div class="">+// CHECK-NEXT: [[RECT_SEL:@.*]]     = {{.*}}[[METH]]{{.*}}</div><div class="">+</div><div class="">+// iOS Specfific</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithCGPoint:{{.*}}</div><div class="">+// CHECK-NEXT: [[CGPOINT_SEL:@.*]]  = {{.*}}[[METH]]{{.*}}</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithCGSize:{{.*}}</div><div class="">+// CHECK-NEXT: [[CGSIZE_SEL:@.*]]   = {{.*}}[[METH]]{{.*}}</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithCGRect:{{.*}}</div><div class="">+// CHECK-NEXT: [[CGRECT_SEL:@.*]]   = {{.*}}[[METH]]{{.*}}</div><div class="">+</div><div class=""><br class=""></div><div class=""><div class="">>> See comment above.</div></div><div class=""><br class=""></div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithPointer:{{.*}}</div><div class="">+// CHECK-NEXT: [[POINTER_SEL:@.*]]  = {{.*}}[[METH]]{{.*}}</div><div class="">+</div><div class="">+// CHECK:      [[METH:@.*]]         = private global{{.*}}valueWithNonretainedObject:{{.*}}</div><div class="">+// CHECK-NEXT: [[NONRET_SEL:@.*]]   = {{.*}}[[METH]]{{.*}}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doRange()</div><div class="">+void doRange() {</div><div class="">+  // CHECK:      [[RANGE:%.*]]     = bitcast %struct._NSRange* {{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]]  = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]       = load i8** [[RANGE_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]      = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  // CHECK:      [[RANGE_PTR:%.*]] = bitcast %struct._NSRange* {{.*}}</div><div class="">+  // CHECK-NEXT: [[P1_PTR:%.*]]    = getelementptr {{.*}} [[RANGE_PTR]], i32 0, i32 0</div><div class="">+  // CHECK-NEXT: [[P1:%.*]]        = load i64* [[P1_PTR]], align 1</div><div class="">+  // CHECK-NEXT: [[P2_PTR:%.*]]    = getelementptr {{.*}} [[RANGE_PTR]], i32 0, i32 1</div><div class="">+  // CHECK-NEXT: [[P2:%.*]]        = load i64* [[P2_PTR]], align 1</div><div class="">+  NSRange ns_range = { .location = 0, .length = 42 };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i64 [[P1]], i64 [[P2]])</div><div class="">+  NSValue *range = @(ns_range);</div><div class="">+  // CHECK:      ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doPoint()</div><div class="">+void doPoint() {</div><div class="">+  // CHECK:      [[POINT:%.*]]     = bitcast %struct._NSPoint* {{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]]  = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]       = load i8** [[POINT_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]      = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  // CHECK:      [[POINT_PTR:%.*]] = bitcast %struct._NSPoint* {{.*}}</div><div class="">+  // CHECK-NEXT: [[P1_PTR:%.*]]    = getelementptr {{.*}} [[POINT_PTR]], i32 0, i32 0</div><div class="">+  // CHECK-NEXT: [[P1:%.*]]        = load double* [[P1_PTR]], align 1</div><div class="">+  // CHECK-NEXT: [[P2_PTR:%.*]]    = getelementptr {{.*}} [[POINT_PTR]], i32 0, i32 1</div><div class="">+  // CHECK-NEXT: [[P2:%.*]]        = load double* [[P2_PTR]], align 1</div><div class="">+  NSPoint ns_point = { .x = 42, .y = 24 };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], double [[P1]], double [[P2]])</div><div class="">+  NSValue *point = @(ns_point);</div><div class="">+  // CHECK:      ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doSize()</div><div class="">+void doSize() {</div><div class="">+  // CHECK:      [[SIZE:%.*]]     = bitcast %struct._NSSize* {{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[SIZE_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  // CHECK:      [[SIZE_PTR:%.*]] = bitcast %struct._NSSize* {{.*}}</div><div class="">+  // CHECK-NEXT: [[P1_PTR:%.*]]   = getelementptr {{.*}} [[SIZE_PTR]], i32 0, i32 0</div><div class="">+  // CHECK-NEXT: [[P1:%.*]]       = load double* [[P1_PTR]], align 1</div><div class="">+  // CHECK-NEXT: [[P2_PTR:%.*]]   = getelementptr {{.*}} [[SIZE_PTR]], i32 0, i32 1</div><div class="">+  // CHECK-NEXT: [[P2:%.*]]       = load double* [[P2_PTR]], align 1</div><div class="">+  NSSize ns_size = { .width = 42, .height = 24 };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], double [[P1]], double [[P2]])</div><div class="">+  NSValue *size = @(ns_size);</div><div class="">+  // CHECK:      ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doRect()</div><div class="">+void doRect() {</div><div class="">+  // CHECK:      [[RECT:%.*]]     = alloca %struct._NSRect{{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[RECT_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  NSPoint ns_point = { .x = 42, .y = 24 };</div><div class="">+  NSSize ns_size = { .width = 42, .height = 24 };</div><div class="">+  NSRect ns_rect = { .origin = ns_point, .size = ns_size };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], %struct._NSRect* byval align 8 [[RECT]])</div><div class="">+  NSValue *rect = @(ns_rect);</div><div class="">+  // CHECK:      ret void</div><div class="">+}</div><div class="">+</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doCGPoint()</div><div class="">+void doCGPoint() {</div><div class="">+  // CHECK:      [[POINT:%.*]]     = bitcast %struct.CGPoint* {{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]]  = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]       = load i8** [[CGPOINT_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]      = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  // CHECK:      [[POINT_PTR:%.*]] = bitcast %struct.CGPoint* {{.*}}</div><div class="">+  // CHECK-NEXT: [[P1_PTR:%.*]]    = getelementptr {{.*}} [[POINT_PTR]], i32 0, i32 0</div><div class="">+  // CHECK-NEXT: [[P1:%.*]]        = load double* [[P1_PTR]], align 1</div><div class="">+  // CHECK-NEXT: [[P2_PTR:%.*]]    = getelementptr {{.*}} [[POINT_PTR]], i32 0, i32 1</div><div class="">+  // CHECK-NEXT: [[P2:%.*]]        = load double* [[P2_PTR]], align 1</div><div class="">+  CGPoint cg_point = { .x = 42, .y = 24 };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], double [[P1]], double [[P2]])</div><div class="">+  NSValue *point = @(cg_point);</div><div class="">+  // CHECK:      ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doCGSize()</div><div class="">+void doCGSize() {</div><div class="">+  // CHECK:      [[SIZE:%.*]]     = bitcast %struct.CGSize* {{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[CGSIZE_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  // CHECK:      [[SIZE_PTR:%.*]] = bitcast %struct.CGSize* {{.*}}</div><div class="">+  // CHECK-NEXT: [[P1_PTR:%.*]]   = getelementptr {{.*}} [[SIZE_PTR]], i32 0, i32 0</div><div class="">+  // CHECK-NEXT: [[P1:%.*]]       = load double* [[P1_PTR]], align 1</div><div class="">+  // CHECK-NEXT: [[P2_PTR:%.*]]   = getelementptr {{.*}} [[SIZE_PTR]], i32 0, i32 1</div><div class="">+  // CHECK-NEXT: [[P2:%.*]]       = load double* [[P2_PTR]], align 1</div><div class="">+  CGSize cg_size = { .width = 42, .height = 24 };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], double [[P1]], double [[P2]])</div><div class="">+  NSValue *size = @(cg_size);</div><div class="">+  // CHECK:      ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doCGRect()</div><div class="">+void doCGRect() {</div><div class="">+  // CHECK:      [[RECT:%.*]]     = alloca %struct.CGRect{{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[CGRECT_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  CGPoint cg_point = { .x = 42, .y = 24 };</div><div class="">+  CGSize cg_size = { .width = 42, .height = 24 };</div><div class="">+  CGRect cg_rect = { .origin = cg_point, .size = cg_size };</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], %struct.CGRect* byval align 8 [[RECT]])</div><div class="">+  NSValue *rect = @(cg_rect);</div><div class="">+  // CHECK:      ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doVoidPointer()</div><div class="">+void doVoidPointer() {</div><div class="">+  // CHECK:      [[POINTER:%.*]]  = alloca i8*{{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[PARAM:%.*]]    = load i8** [[POINTER]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[POINTER_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  const void *pointer = 0;</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM]])</div><div class="">+  NSValue *value = @(pointer);</div><div class="">+  // CHECK:      ret void</div><div class="">+}</div><div class="">+</div><div class="">+// CHECK-LABEL: define void @doNonretainedObject()</div><div class="">+void doNonretainedObject() {</div><div class="">+  // CHECK:      [[OBJ:%.*]]      = alloca i8*{{.*}}</div><div class="">+  // CHECK:      [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]</div><div class="">+  // CHECK:      [[PARAM:%.*]]    = load i8** [[OBJ]]</div><div class="">+  // CHECK:      [[SEL:%.*]]      = load i8** [[NONRET_SEL]]</div><div class="">+  // CHECK:      [[RECV:%.*]]     = bitcast %struct._class_t* [[RECV_PTR]] to i8*</div><div class="">+  id obj;</div><div class="">+  // CHECK:      call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM]])</div><div class="">+  NSValue *object = @(obj);</div><div class="">+  // CHECK:      ret void</div><div class="">+}</div><div class="">diff --git a/test/SemaObjC/boxing-illegal.m b/test/SemaObjC/boxing-illegal.m</div><div class=""><br class=""></div><div class="">>> Sema tests should check for every erroneous situations. Like when NSValue is not available or does not have definition.</div><div class="">>> Or when APIs is not available for iOS or Macosx. </div><div class="">>> Also need a test for __has_feature.</div><div class=""><br class=""></div><div class="">index 59b5c8b..a196370 100644</div><div class="">--- a/test/SemaObjC/boxing-illegal.m</div><div class="">+++ b/test/SemaObjC/boxing-illegal.m</div><div class="">@@ -4,6 +4,8 @@ typedef long NSInteger;</div><div class=""> typedef unsigned long NSUInteger;</div><div class=""> typedef signed char BOOL;</div><div class=""> </div><div class="">+@interface NSValue @end</div><div class="">+</div><div class=""> @interface NSNumber</div><div class=""> @end</div><div class=""> @interface NSNumber (NSNumberCreation)</div><div class="">@@ -34,8 +36,8 @@ void testStruct() {</div><div class=""> }</div><div class=""> </div><div class=""> void testPointers() {</div><div class="">-    void *null = 0;</div><div class="">-    id boxed_null = @(null);        // expected-error {{illegal type 'void *' used in a boxed expression}}</div><div class="">+    float *null = 0;</div><div class="">+    id boxed_null = @(null);        // expected-error {{illegal type 'float *' used in a boxed expression}}</div><div class="">     int numbers[] = { 0, 1, 2 };</div><div class="">     id boxed_numbers = @(numbers);  // expected-error {{illegal type 'int *' used in a boxed expression}}</div><div class=""> }</div><div class="">diff --git a/test/SemaObjC/objc-boxed-expressions-nsvalue.m b/test/SemaObjC/objc-boxed-expressions-nsvalue.m</div><div class="">new file mode 100644</div><div class="">index 0000000..d7033d4</div><div class="">--- /dev/null</div><div class="">+++ b/test/SemaObjC/objc-boxed-expressions-nsvalue.m</div><div class="">@@ -0,0 +1,85 @@</div><div class="">+// RUN: %clang_cc1  -fsyntax-only -fblocks -triple x86_64-apple-darwin10 -verify %s</div><div class="">+</div><div class="">+typedef struct _NSPoint {</div><div class="">+  int dummy;</div><div class="">+} NSPoint;</div><div class="">+</div><div class="">+typedef struct _NSSize {</div><div class="">+  int dummy;</div><div class="">+} NSSize;</div><div class="">+</div><div class="">+typedef struct _NSRect {</div><div class="">+  int dummy;</div><div class="">+} NSRect;</div><div class="">+</div><div class="">+typedef struct _CGPoint {</div><div class="">+  int dummy;</div><div class="">+} CGPoint;</div><div class="">+</div><div class="">+typedef struct _CGSize {</div><div class="">+  int dummy;</div><div class="">+} CGSize;</div><div class="">+</div><div class="">+typedef struct _CGRect {</div><div class="">+  int dummy;</div><div class="">+} CGRect;</div><div class="">+</div><div class="">+typedef struct _NSRange {</div><div class="">+  int dummy;</div><div class="">+} NSRange;</div><div class="">+</div><div class="">+typedef struct _SomeStruct {</div><div class="">+  double d;</div><div class="">+} SomeStruct;</div><div class="">+</div><div class="">+@interface NSObject @end</div><div class="">+</div><div class="">+@interface NSValue</div><div class="">++ (NSValue *)valueWithPoint:(NSPoint)point;</div><div class="">++ (NSValue *)valueWithSize:(NSSize)size;</div><div class="">++ (NSValue *)valueWithRect:(NSRect)rect;</div><div class="">+</div><div class="">++ (NSValue *)valueWithCGPoint:(CGPoint)point;</div><div class="">++ (NSValue *)valueWithCGSize:(CGSize)size;</div><div class="">++ (NSValue *)valueWithCGRect:(CGRect)rect;</div><div class="">+</div><div class="">++ (NSValue *)valueWithRange:(NSRange)range;</div><div class="">+</div><div class="">++ (NSValue *)valueWithPointer:(const void *)pinter;</div><div class="">++ (NSValue *)valueWithNonretainedObject:(id)anObject;</div><div class="">+@end</div><div class="">+</div><div class="">+int main() {</div><div class="">+  NSPoint ns_point;</div><div class="">+  id ns_point_value = @(ns_point);</div><div class="">+</div><div class="">+  NSSize ns_size;</div><div class="">+  id ns_size_value = @(ns_size);</div><div class="">+</div><div class="">+  NSRect ns_rect;</div><div class="">+  id ns_rect_value = @(ns_rect);</div><div class="">+</div><div class="">+  CGPoint cg_point;</div><div class="">+  id cg_point_value = @(cg_point);</div><div class="">+</div><div class="">+  CGSize cg_size;</div><div class="">+  id cg_size_value = @(cg_size);</div><div class="">+</div><div class="">+  CGRect cg_rect;</div><div class="">+  id cg_rect_value = @(cg_rect);</div><div class="">+</div><div class="">+  NSRange ns_range;</div><div class="">+  id ns_range_value = @(ns_range);</div><div class="">+</div><div class="">+  const void *void_pointer;</div><div class="">+  id void_pointer_value = @(void_pointer);</div><div class="">+</div><div class="">+  id id_object;</div><div class="">+  id id_object_value = @(id_object);</div><div class="">+</div><div class="">+  NSObject *ns_object;</div><div class="">+  id ns_object_value = @(ns_object);</div><div class="">+</div><div class="">+  SomeStruct s;</div><div class="">+  id err = @(s); // expected-error{{illegal type 'SomeStruct' (aka 'struct _SomeStruct') used in a boxed expression}}</div><div class="">+}</div><div class="">diff --git a/test/SemaObjCXX/boxing-illegal-types.mm b/test/SemaObjCXX/boxing-illegal-types.mm</div><div class="">index 7729753..70e30c5 100644</div><div class="">--- a/test/SemaObjCXX/boxing-illegal-types.mm</div><div class="">+++ b/test/SemaObjCXX/boxing-illegal-types.mm</div><div class="">@@ -4,6 +4,8 @@ typedef long NSInteger;</div><div class=""> typedef unsigned long NSUInteger;</div><div class=""> typedef signed char BOOL;</div><div class=""> </div><div class="">+@interface NSValue @end</div><div class="">+</div><div class=""> @interface NSNumber</div><div class=""> @end</div><div class=""> @interface NSNumber (NSNumberCreation)</div><div class="">@@ -34,8 +36,8 @@ void testStruct() {</div><div class=""> }</div><div class=""> </div><div class=""> void testPointers() {</div><div class="">-    void *null = 0;</div><div class="">-    id boxed_null = @(null);        // expected-error {{illegal type 'void *' used in a boxed expression}}</div><div class="">+    float *null = 0;</div><div class="">+    id boxed_null = @(null);        // expected-error {{illegal type 'float *' used in a boxed expression}}</div><div class="">     int numbers[] = { 0, 1, 2 };</div><div class="">     id boxed_numbers = @(numbers);  // expected-error {{illegal type 'int *' used in a boxed expression}}</div><div class=""> }</div><div class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">On Dec 7, 2014, at 9:24 AM, AlexDenisov <<a href="mailto:1101.debian@gmail.com" class="">1101.debian@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class="">No worries, that’s fine. At least I have time to improve the patch.</div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class="">Here is the new version, final one, I’d say.</div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class="">I renamed the patch to reflect what it really does.</div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class=""><br class=""></div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class="">In this version:</div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class=""><br class=""></div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class=""> - support for NSRange</div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class=""> - support for NS/CG Rect, Size, Point</div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class=""> - support for Nonretained Object (+ valueWithNonretainedObject:(id)obj )</div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class=""> - support for Pointer (+ valueWithPointer:(const void *)pointer )</div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class=""> - CodeGenObjC tests, both ARC and non-ARC</div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class=""> - SemaObjC tests</div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class=""> - cleanups and fixes based on previous comments</div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class=""><br class=""></div><div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class="">P.S. Previously I mentioned support for structures based on method name (valueWith<StructName>), I don’t know is it a good idea or not and still expect to get any feedback, if it’s possible of course. Otherwise, I would stick to current implementation.</div><div id="bloop_sign_1417972352560997888" class="bloop_sign" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div style="font-family: helvetica, arial; font-size: 13px;" class="">-- <br class="">AlexDenisov</div><div style="font-family: helvetica, arial; font-size: 13px;" class="">Software Engineer, <a href="https://github.com/AlexDenisov" class="">https://github.com/AlexDenisov</a></div></div><span id="cid:099A8A6A-D3F4-4181-8E20-694D0843F9E3@apple.com"><nsvalue_boxed_expressions.patch></span></div></blockquote></div><br class=""></body></html>