[Lldb-commits] [lldb] r157026 - in /lldb/trunk: llvm.zip scripts/clang.amalgamated.diff scripts/clang.check-definition-for-superclasses.diff scripts/clang.complete-type-getObjCLayout.diff scripts/clang.complete-type-isSafeToConvert.diff scripts/clang.decl-printer-reference-type.diff scripts/clang.tail-padded-arrays.diff scripts/clang.template-keyword-fixes.diff source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py

Sean Callanan scallanan at apple.com
Thu May 17 16:29:56 PDT 2012


Author: spyffe
Date: Thu May 17 18:29:56 2012
New Revision: 157026

URL: http://llvm.org/viewvc/llvm-project?rev=157026&view=rev
Log:
I have updated Clang to include support for Objective-C
boxed expressions returning numbers and strings.

I also added boxed expressions to our testcases, and
enabled boxed expressions when libarclite is linked into
the inferior.

Added:
    lldb/trunk/scripts/clang.amalgamated.diff
Removed:
    lldb/trunk/scripts/clang.check-definition-for-superclasses.diff
    lldb/trunk/scripts/clang.complete-type-getObjCLayout.diff
    lldb/trunk/scripts/clang.complete-type-isSafeToConvert.diff
    lldb/trunk/scripts/clang.decl-printer-reference-type.diff
    lldb/trunk/scripts/clang.tail-padded-arrays.diff
    lldb/trunk/scripts/clang.template-keyword-fixes.diff
Modified:
    lldb/trunk/llvm.zip
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
    lldb/trunk/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py

Modified: lldb/trunk/llvm.zip
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/llvm.zip?rev=157026&r1=157025&r2=157026&view=diff
==============================================================================
Binary files - no diff available.

Added: lldb/trunk/scripts/clang.amalgamated.diff
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/clang.amalgamated.diff?rev=157026&view=auto
==============================================================================
--- lldb/trunk/scripts/clang.amalgamated.diff (added)
+++ lldb/trunk/scripts/clang.amalgamated.diff Thu May 17 18:29:56 2012
@@ -0,0 +1,1723 @@
+Index: include/clang/Basic/StmtNodes.td
+===================================================================
+--- include/clang/Basic/StmtNodes.td	(revision 152265)
++++ include/clang/Basic/StmtNodes.td	(working copy)
+@@ -133,7 +133,7 @@
+ 
+ // Obj-C Expressions.
+ def ObjCStringLiteral : DStmt<Expr>;
+-def ObjCNumericLiteral : DStmt<Expr>;
++def ObjCBoxedExpr : DStmt<Expr>;
+ def ObjCArrayLiteral : DStmt<Expr>;
+ def ObjCDictionaryLiteral : DStmt<Expr>;
+ def ObjCEncodeExpr : DStmt<Expr>;
+Index: include/clang/Basic/DiagnosticSemaKinds.td
+===================================================================
+--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 152265)
++++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
+@@ -1489,6 +1489,12 @@
+   "NSNumber must be available to use Objective-C literals">;
+ def err_invalid_nsnumber_type : Error<
+   "%0 is not a valid literal type for NSNumber">;
++def err_undeclared_nsstring : Error<
++  "cannot box a string value because NSString has not been declared">;
++def err_objc_illegal_boxed_expression_type : Error<
++  "illegal type %0 used in a boxed expression">;
++def err_objc_incomplete_boxed_expression_type : Error<
++  "incomplete type %0 used in a boxed expression">;
+ def err_undeclared_nsarray : Error<
+   "NSArray must be available to use Objective-C array literals">;
+ def err_undeclared_nsdictionary : Error<
+Index: include/clang/Sema/Sema.h
+===================================================================
+--- include/clang/Sema/Sema.h	(revision 152265)
++++ include/clang/Sema/Sema.h	(working copy)
+@@ -519,9 +519,21 @@
+   /// \brief The declaration of the Objective-C NSNumber class.
+   ObjCInterfaceDecl *NSNumberDecl;
+   
++  /// \brief Pointer to NSNumber type (NSNumber *).
++  QualType NSNumberPointer;
++  
+   /// \brief The Objective-C NSNumber methods used to create NSNumber literals.
+   ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods];
+   
++  /// \brief The declaration of the Objective-C NSString class.
++  ObjCInterfaceDecl *NSStringDecl;
++
++  /// \brief Pointer to NSString type (NSString *).
++  QualType NSStringPointer;
++  
++  /// \brief The declaration of the stringWithUTF8String: method.
++  ObjCMethodDecl *StringWithUTF8StringMethod;
++
+   /// \brief The declaration of the Objective-C NSArray class.
+   ObjCInterfaceDecl *NSArrayDecl;
+ 
+@@ -3708,7 +3720,7 @@
+     
+   ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S);
+   
+-  /// BuildObjCNumericLiteral - builds an ObjCNumericLiteral AST node for the
++  /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
+   /// numeric literal expression. Type of the expression will be "NSNumber *"
+   /// or "id" if NSNumber is unavailable.
+   ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number);
+@@ -3716,6 +3728,13 @@
+                                   bool Value);
+   ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements);
+   
++  // BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the
++  // '@' prefixed parenthesized expression. The type of the expression will
++  // either be "NSNumber *" or "NSString *" depending on the type of
++  // ValueType, which is allowed to be a built-in numeric type or
++  // "char *" or "const char *".
++  ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr);
++  
+   ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
+                                           Expr *IndexExpr,
+                                           ObjCMethodDecl *getterMethod,
+Index: include/clang/AST/Type.h
+===================================================================
+--- include/clang/AST/Type.h	(revision 152265)
++++ include/clang/AST/Type.h	(working copy)
+@@ -1714,9 +1714,9 @@
+   friend class ASTWriter;
+ };
+ 
+-template <> inline const TypedefType *Type::getAs() const {
+-  return dyn_cast<TypedefType>(this);
+-}
++/// \brief This will check for a TypedefType by removing any existing sugar
++/// until it reaches a TypedefType or a non-sugared type.
++template <> const TypedefType *Type::getAs() const;
+ 
+ // We can do canonical leaf types faster, because we don't have to
+ // worry about preserving child type decoration.
+Index: include/clang/AST/RecursiveASTVisitor.h
+===================================================================
+--- include/clang/AST/RecursiveASTVisitor.h	(revision 152265)
++++ include/clang/AST/RecursiveASTVisitor.h	(working copy)
+@@ -2106,7 +2106,7 @@
+ DEF_TRAVERSE_STMT(ImaginaryLiteral, { })
+ DEF_TRAVERSE_STMT(StringLiteral, { })
+ DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
+-DEF_TRAVERSE_STMT(ObjCNumericLiteral, { })
++DEF_TRAVERSE_STMT(ObjCBoxedExpr, { })
+ DEF_TRAVERSE_STMT(ObjCArrayLiteral, { })
+ DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { })
+   
+Index: include/clang/AST/ExprObjC.h
+===================================================================
+--- include/clang/AST/ExprObjC.h	(revision 152265)
++++ include/clang/AST/ExprObjC.h	(working copy)
+@@ -86,43 +86,45 @@
+   child_range children() { return child_range(); }
+ };
+ 
+-/// ObjCNumericLiteral - used for objective-c numeric literals;
+-/// as in: @42 or @true (c++/objc++) or @__yes (c/objc)
+-class ObjCNumericLiteral : public Expr {
+-  /// Number - expression AST node for the numeric literal
+-  Stmt *Number;
+-  ObjCMethodDecl *ObjCNumericLiteralMethod;
+-  SourceLocation AtLoc;
++/// ObjCBoxedExpr - used for generalized expression boxing.
++/// as in: @(strdup("hello world")) or @(random())
++/// Also used for boxing non-parenthesized numeric literals;
++/// as in: @42 or @true (c++/objc++) or @__yes (c/objc).
++class ObjCBoxedExpr : public Expr {
++  Stmt *SubExpr;
++  ObjCMethodDecl *BoxingMethod;
++  SourceRange Range;
+ public:
+-  ObjCNumericLiteral(Stmt *NL, QualType T, ObjCMethodDecl *method,
+-                     SourceLocation L)
+-  : Expr(ObjCNumericLiteralClass, T, VK_RValue, OK_Ordinary, 
+-         false, false, false, false), Number(NL), 
+-    ObjCNumericLiteralMethod(method), AtLoc(L) {}
+-  explicit ObjCNumericLiteral(EmptyShell Empty)
+-  : Expr(ObjCNumericLiteralClass, Empty) {}
++  ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
++                     SourceRange R)
++  : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary, 
++         E->isTypeDependent(), E->isValueDependent(), 
++         E->isInstantiationDependent(), E->containsUnexpandedParameterPack()), 
++         SubExpr(E), BoxingMethod(method), Range(R) {}
++  explicit ObjCBoxedExpr(EmptyShell Empty)
++  : Expr(ObjCBoxedExprClass, Empty) {}
+   
+-  Expr *getNumber() { return cast<Expr>(Number); }
+-  const Expr *getNumber() const { return cast<Expr>(Number); }
++  Expr *getSubExpr() { return cast<Expr>(SubExpr); }
++  const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+   
+-  ObjCMethodDecl *getObjCNumericLiteralMethod() const {
+-    return ObjCNumericLiteralMethod; 
++  ObjCMethodDecl *getBoxingMethod() const {
++    return BoxingMethod; 
+   }
+-    
+-  SourceLocation getAtLoc() const { return AtLoc; }
+   
++  SourceLocation getAtLoc() const { return Range.getBegin(); }
++  
+   SourceRange getSourceRange() const {
+-    return SourceRange(AtLoc, Number->getSourceRange().getEnd());
++    return Range;
+   }
+-
++  
+   static bool classof(const Stmt *T) {
+-      return T->getStmtClass() == ObjCNumericLiteralClass;
++    return T->getStmtClass() == ObjCBoxedExprClass;
+   }
+-  static bool classof(const ObjCNumericLiteral *) { return true; }
++  static bool classof(const ObjCBoxedExpr *) { return true; }
+   
+   // Iterators
+-  child_range children() { return child_range(&Number, &Number+1); }
+-    
++  child_range children() { return child_range(&SubExpr, &SubExpr+1); }
++  
+   friend class ASTStmtReader;
+ };
+ 
+Index: include/clang/AST/NSAPI.h
+===================================================================
+--- include/clang/AST/NSAPI.h	(revision 152265)
++++ include/clang/AST/NSAPI.h	(working copy)
+@@ -125,10 +125,19 @@
+ 
+   /// \brief Determine the appropriate NSNumber factory method kind for a
+   /// literal of the given type.
+-  static llvm::Optional<NSNumberLiteralMethodKind>
+-      getNSNumberFactoryMethodKind(QualType T);
++  llvm::Optional<NSNumberLiteralMethodKind>
++      getNSNumberFactoryMethodKind(QualType T) const;
+ 
++  /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
++  bool isObjCBOOLType(QualType T) const;
++  /// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
++  bool isObjCNSIntegerType(QualType T) const;
++  /// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
++  bool isObjCNSUIntegerType(QualType T) const;
++
+ private:
++  bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
++
+   ASTContext &Ctx;
+ 
+   mutable IdentifierInfo *ClassIds[NumClassIds];
+@@ -144,6 +153,8 @@
+   /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
+   mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
+   mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
++
++  mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;
+ };
+ 
+ }  // end namespace clang
+Index: include/clang/Parse/Parser.h
+===================================================================
+--- include/clang/Parse/Parser.h	(revision 152265)
++++ include/clang/Parse/Parser.h	(working copy)
+@@ -1497,6 +1497,7 @@
+   ExprResult ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue);
+   ExprResult ParseObjCArrayLiteral(SourceLocation AtLoc);
+   ExprResult ParseObjCDictionaryLiteral(SourceLocation AtLoc);
++  ExprResult ParseObjCBoxedExpr(SourceLocation AtLoc);
+   ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
+   ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
+   ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
+Index: include/clang/Serialization/ASTBitCodes.h
+===================================================================
+--- include/clang/Serialization/ASTBitCodes.h	(revision 152265)
++++ include/clang/Serialization/ASTBitCodes.h	(working copy)
+@@ -1066,7 +1066,7 @@
+       /// \brief An ObjCStringLiteral record.
+       EXPR_OBJC_STRING_LITERAL,
+ 
+-      EXPR_OBJC_NUMERIC_LITERAL,
++      EXPR_OBJC_BOXED_EXPRESSION,
+       EXPR_OBJC_ARRAY_LITERAL,
+       EXPR_OBJC_DICTIONARY_LITERAL,
+ 
+Index: docs/LanguageExtensions.html
+===================================================================
+--- docs/LanguageExtensions.html	(revision 152265)
++++ docs/LanguageExtensions.html	(working copy)
+@@ -87,7 +87,7 @@
+     <li><a href="#objc_instancetype">Related result types</a></li>
+     <li><a href="#objc_arc">Automatic reference counting</a></li>
+     <li><a href="#objc_fixed_enum">Enumerations with a fixed underlying type</a></li>
+-  </ul>
++ </ul>
+ </li>
+ <li><a href="#overloading-in-c">Function Overloading in C</a></li>
+ <li><a href="#complex-list-init">Initializer lists for complex numbers in C</a></li>
+Index: tools/libclang/IndexBody.cpp
+===================================================================
+--- tools/libclang/IndexBody.cpp	(revision 152265)
++++ tools/libclang/IndexBody.cpp	(working copy)
+@@ -90,13 +90,13 @@
+     return true;
+   }
+ 
+-  bool VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
+-    if (ObjCMethodDecl *MD = E->getObjCNumericLiteralMethod())
++  bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
++    if (ObjCMethodDecl *MD = E->getBoxingMethod())
+       IndexCtx.handleReference(MD, E->getLocStart(),
+                                Parent, ParentDC, E, CXIdxEntityRef_Implicit);
+     return true;
+   }
+-
++  
+   bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
+     if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
+       IndexCtx.handleReference(MD, E->getLocStart(),
+Index: tools/libclang/CXCursor.cpp
+===================================================================
+--- tools/libclang/CXCursor.cpp	(revision 152265)
++++ tools/libclang/CXCursor.cpp	(working copy)
+@@ -229,7 +229,7 @@
+   case Stmt::VAArgExprClass:
+   case Stmt::ObjCArrayLiteralClass:
+   case Stmt::ObjCDictionaryLiteralClass:
+-  case Stmt::ObjCNumericLiteralClass:
++  case Stmt::ObjCBoxedExprClass:
+   case Stmt::ObjCSubscriptRefExprClass:
+     K = CXCursor_UnexposedExpr;
+     break;
+Index: lib/Rewrite/RewriteModernObjC.cpp
+===================================================================
+--- lib/Rewrite/RewriteModernObjC.cpp	(revision 152265)
++++ lib/Rewrite/RewriteModernObjC.cpp	(working copy)
+@@ -309,6 +309,10 @@
+     Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
+     Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
+     Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
++    Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp);
++    Stmt *RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp);
++    Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp);
++    Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp);
+     Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
+     void RewriteTryReturnStmts(Stmt *S);
+     void RewriteSyncReturnStmts(Stmt *S, std::string buf);
+@@ -2587,6 +2591,435 @@
+   return cast;
+ }
+ 
++Stmt *RewriteModernObjC::RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp) {
++  unsigned IntSize =
++    static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
++  
++  Expr *FlagExp = IntegerLiteral::Create(*Context, 
++                                         llvm::APInt(IntSize, Exp->getValue()), 
++                                         Context->IntTy, Exp->getLocation());
++  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
++                                            CK_BitCast, FlagExp);
++  ParenExpr *PE = new (Context) ParenExpr(Exp->getLocation(), Exp->getExprLoc(), 
++                                          cast);
++  ReplaceStmt(Exp, PE);
++  return PE;
++}
++
++Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) {
++  // synthesize declaration of helper functions needed in this routine.
++  if (!SelGetUidFunctionDecl)
++    SynthSelGetUidFunctionDecl();
++  // use objc_msgSend() for all.
++  if (!MsgSendFunctionDecl)
++    SynthMsgSendFunctionDecl();
++  if (!GetClassFunctionDecl)
++    SynthGetClassFunctionDecl();
++  
++  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
++  SourceLocation StartLoc = Exp->getLocStart();
++  SourceLocation EndLoc = Exp->getLocEnd();
++  
++  // Synthesize a call to objc_msgSend().
++  SmallVector<Expr*, 4> MsgExprs;
++  SmallVector<Expr*, 4> ClsExprs;
++  QualType argType = Context->getPointerType(Context->CharTy);
++  
++  // Create a call to objc_getClass("<BoxingClass>"). It will be the 1st argument.
++  ObjCMethodDecl *BoxingMethod = Exp->getBoxingMethod();
++  ObjCInterfaceDecl *BoxingClass = BoxingMethod->getClassInterface();
++  
++  IdentifierInfo *clsName = BoxingClass->getIdentifier();
++  ClsExprs.push_back(StringLiteral::Create(*Context,
++                                           clsName->getName(),
++                                           StringLiteral::Ascii, false,
++                                           argType, SourceLocation()));
++  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
++                                               &ClsExprs[0],
++                                               ClsExprs.size(), 
++                                               StartLoc, EndLoc);
++  MsgExprs.push_back(Cls);
++  
++  // Create a call to sel_registerName("<BoxingMethod>:"), etc.
++  // it will be the 2nd argument.
++  SmallVector<Expr*, 4> SelExprs;
++  SelExprs.push_back(StringLiteral::Create(*Context,
++                                           BoxingMethod->getSelector().getAsString(),
++                                           StringLiteral::Ascii, false,
++                                           argType, SourceLocation()));
++  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
++                                                  &SelExprs[0], SelExprs.size(),
++                                                  StartLoc, EndLoc);
++  MsgExprs.push_back(SelExp);
++  
++  // User provided sub-expression is the 3rd, and last, argument.
++  Expr *subExpr  = Exp->getSubExpr();
++  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(subExpr)) {
++    QualType type = ICE->getType();
++    const Expr *SubExpr = ICE->IgnoreParenImpCasts();
++    CastKind CK = CK_BitCast;
++    if (SubExpr->getType()->isIntegralType(*Context) && type->isBooleanType())
++      CK = CK_IntegralToBoolean;
++    subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
++  }
++  MsgExprs.push_back(subExpr);
++  
++  SmallVector<QualType, 4> ArgTypes;
++  ArgTypes.push_back(Context->getObjCIdType());
++  ArgTypes.push_back(Context->getObjCSelType());
++  for (ObjCMethodDecl::param_iterator PI = BoxingMethod->param_begin(),
++       E = BoxingMethod->param_end(); PI != E; ++PI)
++    ArgTypes.push_back((*PI)->getType());
++  
++  QualType returnType = Exp->getType();
++  // Get the type, we will need to reference it in a couple spots.
++  QualType msgSendType = MsgSendFlavor->getType();
++  
++  // Create a reference to the objc_msgSend() declaration.
++  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType,
++                                               VK_LValue, SourceLocation());
++  
++  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
++                                            Context->getPointerType(Context->VoidTy),
++                                            CK_BitCast, DRE);
++  
++  // Now do the "normal" pointer to function cast.
++  QualType castType =
++  getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
++                        BoxingMethod->isVariadic());
++  castType = Context->getPointerType(castType);
++  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
++                                  cast);
++  
++  // Don't forget the parens to enforce the proper binding.
++  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
++  
++  const FunctionType *FT = msgSendType->getAs<FunctionType>();
++  CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
++                                        MsgExprs.size(),
++                                        FT->getResultType(), VK_RValue,
++                                        EndLoc);
++  ReplaceStmt(Exp, CE);
++  return CE;
++}
++
++Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
++  // synthesize declaration of helper functions needed in this routine.
++  if (!SelGetUidFunctionDecl)
++    SynthSelGetUidFunctionDecl();
++  // use objc_msgSend() for all.
++  if (!MsgSendFunctionDecl)
++    SynthMsgSendFunctionDecl();
++  if (!GetClassFunctionDecl)
++    SynthGetClassFunctionDecl();
++  
++  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
++  SourceLocation StartLoc = Exp->getLocStart();
++  SourceLocation EndLoc = Exp->getLocEnd();
++  
++  // Build the expression: __NSContainer_literal(int, ...).arr
++  QualType IntQT = Context->IntTy;
++  QualType NSArrayFType =
++    getSimpleFunctionType(Context->VoidTy, &IntQT, 1, true);
++  std::string NSArrayFName("__NSContainer_literal");
++  FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
++  DeclRefExpr *NSArrayDRE = 
++    new (Context) DeclRefExpr(NSArrayFD, NSArrayFType, VK_RValue,
++                              SourceLocation());
++
++  SmallVector<Expr*, 16> InitExprs;
++  unsigned NumElements = Exp->getNumElements();
++  unsigned UnsignedIntSize = 
++    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
++  Expr *count = IntegerLiteral::Create(*Context,
++                                       llvm::APInt(UnsignedIntSize, NumElements),
++                                       Context->UnsignedIntTy, SourceLocation());
++  InitExprs.push_back(count);
++  for (unsigned i = 0; i < NumElements; i++)
++    InitExprs.push_back(Exp->getElement(i));
++  Expr *NSArrayCallExpr = 
++    new (Context) CallExpr(*Context, NSArrayDRE, &InitExprs[0], InitExprs.size(),
++                           NSArrayFType, VK_LValue, SourceLocation());
++  
++  FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(),
++                                    SourceLocation(),
++                                    &Context->Idents.get("arr"),
++                                    Context->getPointerType(Context->VoidPtrTy), 0,
++                                    /*BitWidth=*/0, /*Mutable=*/true,
++                                    /*HasInit=*/false);
++  MemberExpr *ArrayLiteralME = 
++    new (Context) MemberExpr(NSArrayCallExpr, false, ARRFD, 
++                             SourceLocation(),
++                             ARRFD->getType(), VK_LValue,
++                             OK_Ordinary);
++  QualType ConstIdT = Context->getObjCIdType().withConst();
++  CStyleCastExpr * ArrayLiteralObjects = 
++    NoTypeInfoCStyleCastExpr(Context, 
++                             Context->getPointerType(ConstIdT),
++                             CK_BitCast,
++                             ArrayLiteralME);
++  
++  // Synthesize a call to objc_msgSend().
++  SmallVector<Expr*, 32> MsgExprs;
++  SmallVector<Expr*, 4> ClsExprs;
++  QualType argType = Context->getPointerType(Context->CharTy);
++  QualType expType = Exp->getType();
++  
++  // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
++  ObjCInterfaceDecl *Class = 
++    expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
++  
++  IdentifierInfo *clsName = Class->getIdentifier();
++  ClsExprs.push_back(StringLiteral::Create(*Context,
++                                           clsName->getName(),
++                                           StringLiteral::Ascii, false,
++                                           argType, SourceLocation()));
++  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
++                                               &ClsExprs[0],
++                                               ClsExprs.size(), 
++                                               StartLoc, EndLoc);
++  MsgExprs.push_back(Cls);
++  
++  // Create a call to sel_registerName("arrayWithObjects:count:").
++  // it will be the 2nd argument.
++  SmallVector<Expr*, 4> SelExprs;
++  ObjCMethodDecl *ArrayMethod = Exp->getArrayWithObjectsMethod();
++  SelExprs.push_back(StringLiteral::Create(*Context,
++                                           ArrayMethod->getSelector().getAsString(),
++                                           StringLiteral::Ascii, false,
++                                           argType, SourceLocation()));
++  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
++                                                  &SelExprs[0], SelExprs.size(),
++                                                  StartLoc, EndLoc);
++  MsgExprs.push_back(SelExp);
++  
++  // (const id [])objects
++  MsgExprs.push_back(ArrayLiteralObjects);
++  
++  // (NSUInteger)cnt
++  Expr *cnt = IntegerLiteral::Create(*Context,
++                                     llvm::APInt(UnsignedIntSize, NumElements),
++                                     Context->UnsignedIntTy, SourceLocation());
++  MsgExprs.push_back(cnt);
++  
++  
++  SmallVector<QualType, 4> ArgTypes;
++  ArgTypes.push_back(Context->getObjCIdType());
++  ArgTypes.push_back(Context->getObjCSelType());
++  for (ObjCMethodDecl::param_iterator PI = ArrayMethod->param_begin(),
++       E = ArrayMethod->param_end(); PI != E; ++PI)
++    ArgTypes.push_back((*PI)->getType());
++  
++  QualType returnType = Exp->getType();
++  // Get the type, we will need to reference it in a couple spots.
++  QualType msgSendType = MsgSendFlavor->getType();
++  
++  // Create a reference to the objc_msgSend() declaration.
++  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType,
++                                               VK_LValue, SourceLocation());
++  
++  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
++                                            Context->getPointerType(Context->VoidTy),
++                                            CK_BitCast, DRE);
++  
++  // Now do the "normal" pointer to function cast.
++  QualType castType =
++  getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
++                        ArrayMethod->isVariadic());
++  castType = Context->getPointerType(castType);
++  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
++                                  cast);
++  
++  // Don't forget the parens to enforce the proper binding.
++  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
++  
++  const FunctionType *FT = msgSendType->getAs<FunctionType>();
++  CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
++                                        MsgExprs.size(),
++                                        FT->getResultType(), VK_RValue,
++                                        EndLoc);
++  ReplaceStmt(Exp, CE);
++  return CE;
++}
++
++Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp) {
++  // synthesize declaration of helper functions needed in this routine.
++  if (!SelGetUidFunctionDecl)
++    SynthSelGetUidFunctionDecl();
++  // use objc_msgSend() for all.
++  if (!MsgSendFunctionDecl)
++    SynthMsgSendFunctionDecl();
++  if (!GetClassFunctionDecl)
++    SynthGetClassFunctionDecl();
++  
++  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
++  SourceLocation StartLoc = Exp->getLocStart();
++  SourceLocation EndLoc = Exp->getLocEnd();
++  
++  // Build the expression: __NSContainer_literal(int, ...).arr
++  QualType IntQT = Context->IntTy;
++  QualType NSDictFType =
++    getSimpleFunctionType(Context->VoidTy, &IntQT, 1, true);
++  std::string NSDictFName("__NSContainer_literal");
++  FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
++  DeclRefExpr *NSDictDRE = 
++    new (Context) DeclRefExpr(NSDictFD, NSDictFType, VK_RValue,
++                              SourceLocation());
++  
++  SmallVector<Expr*, 16> KeyExprs;
++  SmallVector<Expr*, 16> ValueExprs;
++  
++  unsigned NumElements = Exp->getNumElements();
++  unsigned UnsignedIntSize = 
++    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
++  Expr *count = IntegerLiteral::Create(*Context,
++                                       llvm::APInt(UnsignedIntSize, NumElements),
++                                       Context->UnsignedIntTy, SourceLocation());
++  KeyExprs.push_back(count);
++  ValueExprs.push_back(count);
++  for (unsigned i = 0; i < NumElements; i++) {
++    ObjCDictionaryElement Element = Exp->getKeyValueElement(i);
++    KeyExprs.push_back(Element.Key);
++    ValueExprs.push_back(Element.Value);
++  }
++  
++  // (const id [])objects
++  Expr *NSValueCallExpr = 
++    new (Context) CallExpr(*Context, NSDictDRE, &ValueExprs[0], ValueExprs.size(),
++                           NSDictFType, VK_LValue, SourceLocation());
++  
++  FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(),
++                                       SourceLocation(),
++                                       &Context->Idents.get("arr"),
++                                       Context->getPointerType(Context->VoidPtrTy), 0,
++                                       /*BitWidth=*/0, /*Mutable=*/true,
++                                       /*HasInit=*/false);
++  MemberExpr *DictLiteralValueME = 
++    new (Context) MemberExpr(NSValueCallExpr, false, ARRFD, 
++                             SourceLocation(),
++                             ARRFD->getType(), VK_LValue,
++                             OK_Ordinary);
++  QualType ConstIdT = Context->getObjCIdType().withConst();
++  CStyleCastExpr * DictValueObjects = 
++    NoTypeInfoCStyleCastExpr(Context, 
++                             Context->getPointerType(ConstIdT),
++                             CK_BitCast,
++                             DictLiteralValueME);
++  // (const id <NSCopying> [])keys
++  Expr *NSKeyCallExpr = 
++    new (Context) CallExpr(*Context, NSDictDRE, &KeyExprs[0], KeyExprs.size(),
++                           NSDictFType, VK_LValue, SourceLocation());
++  
++  MemberExpr *DictLiteralKeyME = 
++    new (Context) MemberExpr(NSKeyCallExpr, false, ARRFD, 
++                             SourceLocation(),
++                             ARRFD->getType(), VK_LValue,
++                             OK_Ordinary);
++  
++  CStyleCastExpr * DictKeyObjects = 
++    NoTypeInfoCStyleCastExpr(Context, 
++                             Context->getPointerType(ConstIdT),
++                             CK_BitCast,
++                             DictLiteralKeyME);
++  
++  
++  
++  // Synthesize a call to objc_msgSend().
++  SmallVector<Expr*, 32> MsgExprs;
++  SmallVector<Expr*, 4> ClsExprs;
++  QualType argType = Context->getPointerType(Context->CharTy);
++  QualType expType = Exp->getType();
++  
++  // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
++  ObjCInterfaceDecl *Class = 
++  expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
++  
++  IdentifierInfo *clsName = Class->getIdentifier();
++  ClsExprs.push_back(StringLiteral::Create(*Context,
++                                           clsName->getName(),
++                                           StringLiteral::Ascii, false,
++                                           argType, SourceLocation()));
++  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
++                                               &ClsExprs[0],
++                                               ClsExprs.size(), 
++                                               StartLoc, EndLoc);
++  MsgExprs.push_back(Cls);
++  
++  // Create a call to sel_registerName("arrayWithObjects:count:").
++  // it will be the 2nd argument.
++  SmallVector<Expr*, 4> SelExprs;
++  ObjCMethodDecl *DictMethod = Exp->getDictWithObjectsMethod();
++  SelExprs.push_back(StringLiteral::Create(*Context,
++                                           DictMethod->getSelector().getAsString(),
++                                           StringLiteral::Ascii, false,
++                                           argType, SourceLocation()));
++  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
++                                                  &SelExprs[0], SelExprs.size(),
++                                                  StartLoc, EndLoc);
++  MsgExprs.push_back(SelExp);
++  
++  // (const id [])objects
++  MsgExprs.push_back(DictValueObjects);
++  
++  // (const id <NSCopying> [])keys
++  MsgExprs.push_back(DictKeyObjects);
++  
++  // (NSUInteger)cnt
++  Expr *cnt = IntegerLiteral::Create(*Context,
++                                     llvm::APInt(UnsignedIntSize, NumElements),
++                                     Context->UnsignedIntTy, SourceLocation());
++  MsgExprs.push_back(cnt);
++  
++  
++  SmallVector<QualType, 8> ArgTypes;
++  ArgTypes.push_back(Context->getObjCIdType());
++  ArgTypes.push_back(Context->getObjCSelType());
++  for (ObjCMethodDecl::param_iterator PI = DictMethod->param_begin(),
++       E = DictMethod->param_end(); PI != E; ++PI) {
++    QualType T = (*PI)->getType();
++    if (const PointerType* PT = T->getAs<PointerType>()) {
++      QualType PointeeTy = PT->getPointeeType();
++      convertToUnqualifiedObjCType(PointeeTy);
++      T = Context->getPointerType(PointeeTy);
++    }
++    ArgTypes.push_back(T);
++  }
++  
++  QualType returnType = Exp->getType();
++  // Get the type, we will need to reference it in a couple spots.
++  QualType msgSendType = MsgSendFlavor->getType();
++  
++  // Create a reference to the objc_msgSend() declaration.
++  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType,
++                                               VK_LValue, SourceLocation());
++  
++  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
++                                            Context->getPointerType(Context->VoidTy),
++                                            CK_BitCast, DRE);
++  
++  // Now do the "normal" pointer to function cast.
++  QualType castType =
++  getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
++                        DictMethod->isVariadic());
++  castType = Context->getPointerType(castType);
++  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
++                                  cast);
++  
++  // Don't forget the parens to enforce the proper binding.
++  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
++  
++  const FunctionType *FT = msgSendType->getAs<FunctionType>();
++  CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
++                                        MsgExprs.size(),
++                                        FT->getResultType(), VK_RValue,
++                                        EndLoc);
++  ReplaceStmt(Exp, CE);
++  return CE;
++}
++
++// struct __rw_objc_super { 
++//   struct objc_object *object; struct objc_object *superClass; 
++// };
+ // struct objc_super { struct objc_object *receiver; struct objc_class *super; };
+ QualType RewriteModernObjC::getSuperStructType() {
+   if (!SuperStructDecl) {
+@@ -4801,6 +5234,19 @@
+ 
+   if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
+     return RewriteObjCStringLiteral(AtString);
++  
++  if (ObjCBoolLiteralExpr *BoolLitExpr = dyn_cast<ObjCBoolLiteralExpr>(S))
++    return RewriteObjCBoolLiteralExpr(BoolLitExpr);
++  
++  if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(S))
++    return RewriteObjCBoxedExpr(BoxedExpr);
++  
++  if (ObjCArrayLiteral *ArrayLitExpr = dyn_cast<ObjCArrayLiteral>(S))
++    return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
++  
++  if (ObjCDictionaryLiteral *DictionaryLitExpr = 
++        dyn_cast<ObjCDictionaryLiteral>(S))
++    return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
+ 
+   if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
+ #if 0
+Index: lib/Sema/TreeTransform.h
+===================================================================
+--- lib/Sema/TreeTransform.h	(revision 152265)
++++ lib/Sema/TreeTransform.h	(working copy)
+@@ -2211,6 +2211,14 @@
+                                                 RParenLoc);
+   }
+ 
++  /// \brief Build a new Objective-C boxed expression.
++  ///
++  /// By default, performs semantic analysis to build the new expression.
++  /// Subclasses may override this routine to provide different behavior.
++  ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
++    return getSema().BuildObjCBoxedExpr(SR, ValueExpr);
++  }
++  
+   /// \brief Build a new Objective-C array literal.
+   ///
+   /// By default, performs semantic analysis to build the new expression.
+@@ -8298,8 +8306,16 @@
+ 
+ template<typename Derived>
+ ExprResult
+-TreeTransform<Derived>::TransformObjCNumericLiteral(ObjCNumericLiteral *E) {
+-  return SemaRef.MaybeBindToTemporary(E);
++TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
++  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
++  if (SubExpr.isInvalid())
++    return ExprError();
++
++  if (!getDerived().AlwaysRebuild() &&
++      SubExpr.get() == E->getSubExpr())
++    return SemaRef.Owned(E);
++
++  return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
+ }
+ 
+ template<typename Derived>
+Index: lib/Sema/SemaExprCXX.cpp
+===================================================================
+--- lib/Sema/SemaExprCXX.cpp	(revision 152265)
++++ lib/Sema/SemaExprCXX.cpp	(working copy)
+@@ -4469,8 +4469,8 @@
+       ObjCMethodDecl *D = 0;
+       if (ObjCMessageExpr *Send = dyn_cast<ObjCMessageExpr>(E)) {
+         D = Send->getMethodDecl();
+-      } else if (ObjCNumericLiteral *NumLit = dyn_cast<ObjCNumericLiteral>(E)) {
+-        D = NumLit->getObjCNumericLiteralMethod();
++      } else if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(E)) {
++        D = BoxedExpr->getBoxingMethod();
+       } else if (ObjCArrayLiteral *ArrayLit = dyn_cast<ObjCArrayLiteral>(E)) {
+         D = ArrayLit->getArrayWithObjectsMethod();
+       } else if (ObjCDictionaryLiteral *DictLit
+Index: lib/Sema/SemaExceptionSpec.cpp
+===================================================================
+--- lib/Sema/SemaExceptionSpec.cpp	(revision 152265)
++++ lib/Sema/SemaExceptionSpec.cpp	(working copy)
+@@ -726,4 +726,4 @@
+                                   New->getLocation());
+ }
+ 
+-} // end namespace clang
++}
+Index: lib/Sema/SemaChecking.cpp
+===================================================================
+--- lib/Sema/SemaChecking.cpp	(revision 152265)
++++ lib/Sema/SemaChecking.cpp	(working copy)
+@@ -4416,12 +4416,16 @@
+ 
+   // Don't consider sizes resulting from macro expansions or template argument
+   // substitution to form C89 tail-padded arrays.
+-  ConstantArrayTypeLoc TL =
+-    cast<ConstantArrayTypeLoc>(FD->getTypeSourceInfo()->getTypeLoc());
+-  const Expr *SizeExpr = dyn_cast<IntegerLiteral>(TL.getSizeExpr());
+-  if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
+-    return false;
+ 
++  TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
++  if (TInfo) {
++    ConstantArrayTypeLoc TL =
++      cast<ConstantArrayTypeLoc>(TInfo->getTypeLoc());
++    const Expr *SizeExpr = dyn_cast<IntegerLiteral>(TL.getSizeExpr());
++    if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
++      return false;
++  }
++
+   const RecordDecl *RD = dyn_cast<RecordDecl>(FD->getDeclContext());
+   if (!RD) return false;
+   if (RD->isUnion()) return false;
+Index: lib/Sema/SemaExprObjC.cpp
+===================================================================
+--- lib/Sema/SemaExprObjC.cpp	(revision 152265)
++++ lib/Sema/SemaExprObjC.cpp	(working copy)
+@@ -111,7 +111,7 @@
+       Ty = Context.getObjCIdType();
+     }
+   } else {
+-    IdentifierInfo *NSIdent = &Context.Idents.get("NSString");
++    IdentifierInfo *NSIdent = NSAPIObj->getNSClassId(NSAPI::ClassId_NSString);
+     NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLoc,
+                                      LookupOrdinaryName);
+     if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
+@@ -143,41 +143,70 @@
+ /// \brief Retrieve the NSNumber factory method that should be used to create
+ /// an Objective-C literal for the given type.
+ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc,
+-                                                QualType T, QualType ReturnType,
+-                                                SourceRange Range) {
++                                                QualType NumberType,
++                                                bool isLiteral = false,
++                                                SourceRange R = SourceRange()) {
+   llvm::Optional<NSAPI::NSNumberLiteralMethodKind> Kind 
+-    = S.NSAPIObj->getNSNumberFactoryMethodKind(T);
++    = S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);
+   
+   if (!Kind) {
+-    S.Diag(Loc, diag::err_invalid_nsnumber_type)
+-      << T << Range;
++    if (isLiteral) {
++      S.Diag(Loc, diag::err_invalid_nsnumber_type)
++        << NumberType << R;
++    }
+     return 0;
+   }
+-    
++  
+   // If we already looked up this method, we're done.
+   if (S.NSNumberLiteralMethods[*Kind])
+     return S.NSNumberLiteralMethods[*Kind];
+   
+   Selector Sel = S.NSAPIObj->getNSNumberLiteralSelector(*Kind,
+                                                         /*Instance=*/false);
++
++  ASTContext &CX = S.Context;
+   
++  // Look up the NSNumber class, if we haven't done so already. It's cached
++  // in the Sema instance.
++  if (!S.NSNumberDecl) {
++    IdentifierInfo *NSNumberId = S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSNumber);
++    if (S.getLangOptions().DebuggerObjCLiteral) {
++      // Create a stub definition of NSNumber.
++      S.NSNumberDecl =  ObjCInterfaceDecl::Create (CX,
++                                                   CX.getTranslationUnitDecl(),
++                                                   SourceLocation(),  NSNumberId,
++                                                   0, SourceLocation());
++    } else {
++      // Otherwise, require a declaration of NSNumber.
++      NamedDecl *IF = S.LookupSingleName(S.TUScope, NSNumberId,
++                                         Loc, Sema::LookupOrdinaryName);
++      S.NSNumberDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
++      if (!S.NSNumberDecl || !S.NSNumberDecl->hasDefinition()) {
++        S.Diag(Loc, diag::err_undeclared_nsnumber);
++        return 0;
++      }
++    }
++    
++    // generate the pointer to NSNumber type.
++    S.NSNumberPointer = CX.getObjCObjectPointerType(CX.getObjCInterfaceType(S.NSNumberDecl));
++  }
++  
+   // Look for the appropriate method within NSNumber.
+   ObjCMethodDecl *Method = S.NSNumberDecl->lookupClassMethod(Sel);;
+   if (!Method && S.getLangOptions().DebuggerObjCLiteral) {
++    // create a stub definition this NSNumber factory method.
+     TypeSourceInfo *ResultTInfo = 0;
+-    Method = ObjCMethodDecl::Create(S.Context, SourceLocation(), SourceLocation(), Sel,
+-                           ReturnType,
+-                           ResultTInfo,
+-                           S.Context.getTranslationUnitDecl(),
+-                           false /*Instance*/, false/*isVariadic*/,
+-                           /*isSynthesized=*/false,
+-                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
+-                           ObjCMethodDecl::Required,
+-                           false);
++    Method = ObjCMethodDecl::Create(CX, SourceLocation(), SourceLocation(), Sel,
++                                    S.NSNumberPointer, ResultTInfo, S.NSNumberDecl,
++                                    /*isInstance=*/false, /*isVariadic=*/false,
++                                    /*isSynthesized=*/false,
++                                    /*isImplicitlyDeclared=*/true,
++                                    /*isDefined=*/false, ObjCMethodDecl::Required,
++                                    /*HasRelatedResultType=*/false);
+     ParmVarDecl *value = ParmVarDecl::Create(S.Context, Method,
+                                              SourceLocation(), SourceLocation(),
+-                                             &S.Context.Idents.get("value"),
+-                                             T, /*TInfo=*/0, SC_None, SC_None, 0);
++                                             &CX.Idents.get("value"),
++                                             NumberType, /*TInfo=*/0, SC_None, SC_None, 0);
+     Method->setMethodParams(S.Context, value, ArrayRef<SourceLocation>());
+   }
+ 
+@@ -202,29 +231,9 @@
+   return Method;
+ }
+ 
+-/// BuildObjCNumericLiteral - builds an ObjCNumericLiteral AST node for the
+-/// numeric literal expression. Type of the expression will be "NSNumber *"
+-/// or "id" if NSNumber is unavailable.
++/// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
++/// numeric literal expression. Type of the expression will be "NSNumber *".
+ ExprResult Sema::BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number) {
+-  // Look up the NSNumber class, if we haven't done so already.
+-  if (!NSNumberDecl) {
+-    NamedDecl *IF = LookupSingleName(TUScope,
+-                                NSAPIObj->getNSClassId(NSAPI::ClassId_NSNumber),
+-                                AtLoc, LookupOrdinaryName);
+-    NSNumberDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
+-    
+-    if (!NSNumberDecl && getLangOptions().DebuggerObjCLiteral)
+-      NSNumberDecl =  ObjCInterfaceDecl::Create (Context,
+-                        Context.getTranslationUnitDecl(),
+-                        SourceLocation(), 
+-                        NSAPIObj->getNSClassId(NSAPI::ClassId_NSNumber),
+-                        0, SourceLocation());
+-    if (!NSNumberDecl) {
+-      Diag(AtLoc, diag::err_undeclared_nsnumber);
+-      return ExprError();
+-    }
+-  }
+-  
+   // Determine the type of the literal.
+   QualType NumberType = Number->getType();
+   if (CharacterLiteral *Char = dyn_cast<CharacterLiteral>(Number)) {
+@@ -249,29 +258,29 @@
+     }
+   }
+   
+-  ObjCMethodDecl *Method = 0;
+   // Look for the appropriate method within NSNumber.
+   // Construct the literal.
+-  QualType Ty
+-    = Context.getObjCObjectPointerType(
+-                                    Context.getObjCInterfaceType(NSNumberDecl));
+-  Method  = getNSNumberFactoryMethod(*this, AtLoc, 
+-                                     NumberType, Ty, 
+-                                     Number->getSourceRange());
+-
++  SourceRange NR(Number->getSourceRange());
++  ObjCMethodDecl *Method = getNSNumberFactoryMethod(*this, AtLoc, NumberType,
++                                                    true, NR);
+   if (!Method)
+     return ExprError();
+ 
+   // Convert the number to the type that the parameter expects.
+-  QualType ElementT = Method->param_begin()[0]->getType();
+-  ExprResult ConvertedNumber = PerformImplicitConversion(Number, ElementT,
+-                                                         AA_Sending);
++  ParmVarDecl *ParamDecl = Method->param_begin()[0];
++  InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
++                                                                    ParamDecl);
++  ExprResult ConvertedNumber = PerformCopyInitialization(Entity,
++                                                         SourceLocation(),
++                                                         Owned(Number));
+   if (ConvertedNumber.isInvalid())
+     return ExprError();
+   Number = ConvertedNumber.get();
+   
++  // Use the effective source range of the literal, including the leading '@'.
+   return MaybeBindToTemporary(
+-           new (Context) ObjCNumericLiteral(Number, Ty, Method, AtLoc));
++           new (Context) ObjCBoxedExpr(Number, NSNumberPointer, Method,
++                                       SourceRange(AtLoc, NR.getEnd())));
+ }
+ 
+ ExprResult Sema::ActOnObjCBoolLiteral(SourceLocation AtLoc, 
+@@ -385,6 +394,154 @@
+            Element->getLocStart(), Element);
+ }
+ 
++ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
++  if (ValueExpr->isTypeDependent()) {
++    ObjCBoxedExpr *BoxedExpr = 
++      new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, NULL, SR);
++    return Owned(BoxedExpr);
++  }
++  ObjCMethodDecl *BoxingMethod = NULL;
++  QualType BoxedType;
++  // Convert the expression to an RValue, so we can check for pointer types...
++  ExprResult RValue = DefaultFunctionArrayLvalueConversion(ValueExpr);
++  if (RValue.isInvalid()) {
++    return ExprError();
++  }
++  ValueExpr = RValue.get();
++  QualType ValueType(ValueExpr->getType());
++  if (const PointerType *PT = ValueType->getAs<PointerType>()) {
++    QualType PointeeType = PT->getPointeeType();
++    if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {
++      IdentifierInfo *NSStringId =
++        NSAPIObj->getNSClassId(NSAPI::ClassId_NSString);
++      if (getLangOptions().DebuggerObjCLiteral) {
++        // Support boxed expressions in the debugger w/o NSString declaration.
++        NSStringDecl = ObjCInterfaceDecl::Create(Context,
++                                                 Context.getTranslationUnitDecl(),
++                                                 SourceLocation(), NSStringId,
++                                                 0, SourceLocation());
++      }
++      else {
++        NamedDecl *Decl = LookupSingleName(TUScope, NSStringId,
++                                           SR.getBegin(), LookupOrdinaryName);
++        NSStringDecl = dyn_cast_or_null<ObjCInterfaceDecl>(Decl);
++
++        if (!NSStringDecl || !NSStringDecl->hasDefinition()) {
++          Diag(SR.getBegin(), diag::err_undeclared_nsstring);
++          return ExprError();
++        }
++      }
++      assert(NSStringDecl && "NSStringDecl should not be NULL");
++      NSStringPointer =
++        Context.getObjCObjectPointerType(Context.getObjCInterfaceType(NSStringDecl));
++      
++      if (!StringWithUTF8StringMethod) {
++        IdentifierInfo *II = &Context.Idents.get("stringWithUTF8String");
++        Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);
++
++        // Look for the appropriate method within NSString.
++        StringWithUTF8StringMethod = NSStringDecl->lookupClassMethod(stringWithUTF8String);
++        if (!StringWithUTF8StringMethod && getLangOptions().DebuggerObjCLiteral) {
++          // Debugger needs to work even if NSString hasn't been defined.
++          TypeSourceInfo *ResultTInfo = 0;
++          ObjCMethodDecl *M =
++            ObjCMethodDecl::Create(Context, SourceLocation(), SourceLocation(),
++                                   stringWithUTF8String, NSStringPointer,
++                                   ResultTInfo, NSStringDecl,
++                                   /*isInstance=*/false, /*isVariadic=*/false,
++                                   /*isSynthesized=*/false,
++                                   /*isImplicitlyDeclared=*/true,
++                                   /*isDefined=*/false,
++                                   ObjCMethodDecl::Required,
++                                   /*HasRelatedResultType=*/false);
++          ParmVarDecl *value =
++            ParmVarDecl::Create(Context, M,
++                                SourceLocation(), SourceLocation(),
++                                &Context.Idents.get("value"),
++                                Context.getPointerType(Context.CharTy.withConst()),
++                                /*TInfo=*/0,
++                                SC_None, SC_None, 0);
++          M->setMethodParams(Context, value, ArrayRef<SourceLocation>());
++          StringWithUTF8StringMethod = M;
++        }
++        assert(StringWithUTF8StringMethod &&
++               "StringWithUTF8StringMethod should not be NULL");
++      }
++      
++      BoxingMethod = StringWithUTF8StringMethod;
++      BoxedType = NSStringPointer;
++    }
++  } else if (ValueType->isBuiltinType()) {
++    // The other types we support are numeric, char and BOOL/bool. We could also
++    // provide limited support for structure types, such as NSRange, NSRect, and
++    // NSSize. See NSValue (NSValueGeometryExtensions) in <Foundation/NSGeometry.h>
++    // for more details.
++
++    // Check for a top-level character literal.
++    if (const CharacterLiteral *Char =
++        dyn_cast<CharacterLiteral>(ValueExpr->IgnoreParens())) {
++      // In C, character literals have type 'int'. That's not the type we want
++      // to use to determine the Objective-c literal kind.
++      switch (Char->getKind()) {
++      case CharacterLiteral::Ascii:
++        ValueType = Context.CharTy;
++        break;
++        
++      case CharacterLiteral::Wide:
++        ValueType = Context.getWCharType();
++        break;
++        
++      case CharacterLiteral::UTF16:
++        ValueType = Context.Char16Ty;
++        break;
++        
++      case CharacterLiteral::UTF32:
++        ValueType = Context.Char32Ty;
++        break;
++      }
++    }
++    
++    // FIXME:  Do I need to do anything special with BoolTy expressions?
++    
++    // Look for the appropriate method within NSNumber.
++    BoxingMethod = getNSNumberFactoryMethod(*this, SR.getBegin(), ValueType);
++    BoxedType = NSNumberPointer;
++
++  } else if (const EnumType *ET = ValueType->getAs<EnumType>()) {
++    if (!ET->getDecl()->isComplete()) {
++      Diag(SR.getBegin(), diag::err_objc_incomplete_boxed_expression_type)
++        << ValueType << ValueExpr->getSourceRange();
++      return ExprError();
++    }
++
++    BoxingMethod = getNSNumberFactoryMethod(*this, SR.getBegin(),
++                                            ET->getDecl()->getIntegerType());
++    BoxedType = NSNumberPointer;
++  }
++
++  if (!BoxingMethod) {
++    Diag(SR.getBegin(), diag::err_objc_illegal_boxed_expression_type)
++      << ValueType << ValueExpr->getSourceRange();
++    return ExprError();
++  }
++  
++  // Convert the expression to the type that the parameter requires.
++  ParmVarDecl *ParamDecl = BoxingMethod->param_begin()[0];
++  InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
++                                                                    ParamDecl);
++  ExprResult ConvertedValueExpr = PerformCopyInitialization(Entity,
++                                                            SourceLocation(),
++                                                            Owned(ValueExpr));
++  if (ConvertedValueExpr.isInvalid())
++    return ExprError();
++  ValueExpr = ConvertedValueExpr.get();
++  
++  ObjCBoxedExpr *BoxedExpr = 
++    new (Context) ObjCBoxedExpr(ValueExpr, BoxedType,
++                                      BoxingMethod, SR);
++  return MaybeBindToTemporary(BoxedExpr);
++}
++
+ ExprResult Sema::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
+                                         Expr *IndexExpr,
+                                         ObjCMethodDecl *getterMethod,
+@@ -417,21 +574,22 @@
+ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
+   // Look up the NSArray class, if we haven't done so already.
+   if (!NSArrayDecl) {
+-    NamedDecl *IF = LookupSingleName(TUScope,
+-                                 NSAPIObj->getNSClassId(NSAPI::ClassId_NSArray),
+-                                 SR.getBegin(),
+-                                 LookupOrdinaryName);
+-    NSArrayDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
+-    if (!NSArrayDecl && getLangOptions().DebuggerObjCLiteral)
++    if (getLangOptions().DebuggerObjCLiteral) {
+       NSArrayDecl =  ObjCInterfaceDecl::Create (Context,
+                             Context.getTranslationUnitDecl(),
+                             SourceLocation(),
+                             NSAPIObj->getNSClassId(NSAPI::ClassId_NSArray),
+                             0, SourceLocation());
+-
+-    if (!NSArrayDecl) {
+-      Diag(SR.getBegin(), diag::err_undeclared_nsarray);
+-      return ExprError();
++    } else {
++      NamedDecl *IF = LookupSingleName(TUScope,
++                                   NSAPIObj->getNSClassId(NSAPI::ClassId_NSArray),
++                                   SR.getBegin(),
++                                   LookupOrdinaryName);
++      NSArrayDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
++      if (!NSArrayDecl) {
++        Diag(SR.getBegin(), diag::err_undeclared_nsarray);
++        return ExprError();
++      }
+     }
+   }
+   
+Index: lib/Sema/Sema.cpp
+===================================================================
+--- lib/Sema/Sema.cpp	(revision 152265)
++++ lib/Sema/Sema.cpp	(working copy)
+@@ -90,7 +90,9 @@
+     PackContext(0), MSStructPragmaOn(false), VisContext(0),
+     ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0),
+     IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
+-    NSNumberDecl(0), NSArrayDecl(0), ArrayWithObjectsMethod(0), 
++    NSNumberDecl(0),
++    NSStringDecl(0), StringWithUTF8StringMethod(0),
++    NSArrayDecl(0), ArrayWithObjectsMethod(0), 
+     NSDictionaryDecl(0), DictionaryWithObjectsMethod(0),
+     GlobalNewDeleteDeclared(false), 
+     ObjCShouldCallSuperDealloc(false),
+Index: lib/AST/DeclObjC.cpp
+===================================================================
+--- lib/AST/DeclObjC.cpp	(revision 152265)
++++ lib/AST/DeclObjC.cpp	(working copy)
+@@ -330,6 +330,10 @@
+     LoadExternalDefinition();
+ 
+   while (ClassDecl != NULL) {
++    // FIXME: Should make sure no callers ever do this.
++    if (!ClassDecl->hasDefinition())
++      return 0;
++        
+     if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
+       return MethodDecl;
+ 
+Index: lib/AST/NSAPI.cpp
+===================================================================
+--- lib/AST/NSAPI.cpp	(revision 152265)
++++ lib/AST/NSAPI.cpp	(working copy)
+@@ -13,7 +13,7 @@
+ using namespace clang;
+ 
+ NSAPI::NSAPI(ASTContext &ctx)
+-  : Ctx(ctx), ClassIds() {
++  : Ctx(ctx), ClassIds(), BOOLId(0), NSIntegerId(0), NSUIntegerId(0) {
+ }
+ 
+ IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
+@@ -250,11 +250,22 @@
+ }
+ 
+ llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
+-NSAPI::getNSNumberFactoryMethodKind(QualType T) {
++NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
+   const BuiltinType *BT = T->getAs<BuiltinType>();
+   if (!BT)
+     return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
+-  
++
++  const TypedefType *TDT = T->getAs<TypedefType>();
++  if (TDT) {
++    QualType TDTTy = QualType(TDT, 0);
++    if (isObjCBOOLType(TDTTy))
++      return NSAPI::NSNumberWithBool;
++    if (isObjCNSIntegerType(TDTTy))
++      return NSAPI::NSNumberWithInteger;
++    if (isObjCNSUIntegerType(TDTTy))
++      return NSAPI::NSNumberWithUnsignedInteger;
++  }
++
+   switch (BT->getKind()) {
+   case BuiltinType::Char_S:
+   case BuiltinType::SChar:
+@@ -309,3 +320,35 @@
+   
+   return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
+ }
++
++/// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
++bool NSAPI::isObjCBOOLType(QualType T) const {
++  return isObjCTypedef(T, "BOOL", BOOLId);
++}
++/// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
++bool NSAPI::isObjCNSIntegerType(QualType T) const {
++  return isObjCTypedef(T, "NSInteger", NSIntegerId);
++}
++/// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
++bool NSAPI::isObjCNSUIntegerType(QualType T) const {
++  return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
++}
++
++bool NSAPI::isObjCTypedef(QualType T,
++                          StringRef name, IdentifierInfo *&II) const {
++  if (!Ctx.getLangOptions().ObjC1)
++    return false;
++  if (T.isNull())
++    return false;
++
++  if (!II)
++    II = &Ctx.Idents.get(name);
++
++  while (const TypedefType *TDT = T->getAs<TypedefType>()) {
++    if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
++      return true;
++    T = TDT->desugar();
++  }
++
++  return false;
++}
+Index: lib/AST/DeclPrinter.cpp
+===================================================================
+--- lib/AST/DeclPrinter.cpp	(revision 152265)
++++ lib/AST/DeclPrinter.cpp	(working copy)
+@@ -114,6 +114,8 @@
+       BaseType = FTy->getResultType();
+     else if (const VectorType *VTy = BaseType->getAs<VectorType>())
+       BaseType = VTy->getElementType();
++    else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>())
++      BaseType = RTy->getPointeeType();
+     else
+       llvm_unreachable("Unknown declarator!");
+   }
+Index: lib/AST/Type.cpp
+===================================================================
+--- lib/AST/Type.cpp	(revision 152265)
++++ lib/AST/Type.cpp	(working copy)
+@@ -288,6 +288,28 @@
+   return T;
+ }
+ 
++/// \brief This will check for a TypedefType by removing any existing sugar
++/// until it reaches a TypedefType or a non-sugared type.
++template <> const TypedefType *Type::getAs() const {
++  const Type *Cur = this;
++
++  while (true) {
++    if (const TypedefType *TDT = dyn_cast<TypedefType>(Cur))
++      return TDT;
++    switch (Cur->getTypeClass()) {
++#define ABSTRACT_TYPE(Class, Parent)
++#define TYPE(Class, Parent) \
++    case Class: { \
++      const Class##Type *Ty = cast<Class##Type>(Cur); \
++      if (!Ty->isSugared()) return 0; \
++      Cur = Ty->desugar().getTypePtr(); \
++      break; \
++    }
++#include "clang/AST/TypeNodes.def"
++    }
++  }
++}
++
+ /// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic
+ /// sugar off the given type.  This should produce an object of the
+ /// same dynamic type as the canonical type.
+Index: lib/AST/RecordLayoutBuilder.cpp
+===================================================================
+--- lib/AST/RecordLayoutBuilder.cpp	(revision 152265)
++++ lib/AST/RecordLayoutBuilder.cpp	(working copy)
+@@ -2313,6 +2313,8 @@
+ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
+                           const ObjCImplementationDecl *Impl) const {
+   // Retrieve the definition
++  if (D->hasExternalLexicalStorage() && !D->getDefinition())
++    getExternalSource()->CompleteType(const_cast<ObjCInterfaceDecl*>(D));
+   D = D->getDefinition();
+   assert(D && D->isThisDeclarationADefinition() && "Invalid interface decl!");
+ 
+Index: lib/AST/ExprConstant.cpp
+===================================================================
+--- lib/AST/ExprConstant.cpp	(revision 152265)
++++ lib/AST/ExprConstant.cpp	(working copy)
+@@ -3054,7 +3054,7 @@
+   bool VisitUnaryAddrOf(const UnaryOperator *E);
+   bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
+       { return Success(E); }
+-  bool VisitObjCNumericLiteral(const ObjCNumericLiteral *E)
++  bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
+       { return Success(E); }    
+   bool VisitAddrLabelExpr(const AddrLabelExpr *E)
+       { return Success(E); }
+@@ -4210,7 +4210,7 @@
+ /// character of a string literal.
+ template<typename LValue>
+ static bool EvaluateBuiltinConstantPForLValue(const LValue &LV) {
+-  const Expr *E = LV.getLValueBase().dyn_cast<const Expr*>();
++  const Expr *E = LV.getLValueBase().template dyn_cast<const Expr*>();
+   return E && isa<StringLiteral>(E) && LV.getLValueOffset().isZero();
+ }
+ 
+@@ -6259,7 +6259,7 @@
+   case Expr::CXXDependentScopeMemberExprClass:
+   case Expr::UnresolvedMemberExprClass:
+   case Expr::ObjCStringLiteralClass:
+-  case Expr::ObjCNumericLiteralClass:
++  case Expr::ObjCBoxedExprClass:
+   case Expr::ObjCArrayLiteralClass:
+   case Expr::ObjCDictionaryLiteralClass:
+   case Expr::ObjCEncodeExprClass:
+Index: lib/AST/ItaniumMangle.cpp
+===================================================================
+--- lib/AST/ItaniumMangle.cpp	(revision 152265)
++++ lib/AST/ItaniumMangle.cpp	(working copy)
+@@ -2374,7 +2374,7 @@
+   case Expr::ObjCProtocolExprClass:
+   case Expr::ObjCSelectorExprClass:
+   case Expr::ObjCStringLiteralClass:
+-  case Expr::ObjCNumericLiteralClass:
++  case Expr::ObjCBoxedExprClass:
+   case Expr::ObjCArrayLiteralClass:
+   case Expr::ObjCDictionaryLiteralClass:
+   case Expr::ObjCSubscriptRefExprClass:
+Index: lib/AST/StmtPrinter.cpp
+===================================================================
+--- lib/AST/StmtPrinter.cpp	(revision 152265)
++++ lib/AST/StmtPrinter.cpp	(working copy)
+@@ -1679,9 +1679,9 @@
+   VisitStringLiteral(Node->getString());
+ }
+ 
+-void StmtPrinter::VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
++void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
+   OS << "@";
+-  Visit(E->getNumber());
++  Visit(E->getSubExpr());
+ }
+ 
+ void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
+Index: lib/AST/StmtProfile.cpp
+===================================================================
+--- lib/AST/StmtProfile.cpp	(revision 152265)
++++ lib/AST/StmtProfile.cpp	(working copy)
+@@ -982,7 +982,7 @@
+   VisitExpr(S);
+ }
+ 
+-void StmtProfiler::VisitObjCNumericLiteral(const ObjCNumericLiteral *E) {
++void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
+   VisitExpr(E);
+ }
+ 
+Index: lib/AST/Expr.cpp
+===================================================================
+--- lib/AST/Expr.cpp	(revision 152265)
++++ lib/AST/Expr.cpp	(working copy)
+@@ -2100,7 +2100,7 @@
+   case ObjCArrayLiteralClass:
+   case ObjCBoolLiteralExprClass:
+   case ObjCDictionaryLiteralClass:
+-  case ObjCNumericLiteralClass:
++  case ObjCBoxedExprClass:
+     return CT_Can;
+ 
+     // Many other things have subexpressions, so we have to test those.
+Index: lib/AST/ExprClassification.cpp
+===================================================================
+--- lib/AST/ExprClassification.cpp	(revision 152265)
++++ lib/AST/ExprClassification.cpp	(working copy)
+@@ -158,7 +158,7 @@
+   case Expr::ObjCSelectorExprClass:
+   case Expr::ObjCProtocolExprClass:
+   case Expr::ObjCStringLiteralClass:
+-  case Expr::ObjCNumericLiteralClass:
++  case Expr::ObjCBoxedExprClass:
+   case Expr::ObjCArrayLiteralClass:
+   case Expr::ObjCDictionaryLiteralClass:
+   case Expr::ObjCBoolLiteralExprClass:
+Index: lib/Lex/PPMacroExpansion.cpp
+===================================================================
+--- lib/Lex/PPMacroExpansion.cpp	(revision 152265)
++++ lib/Lex/PPMacroExpansion.cpp	(working copy)
+@@ -634,6 +634,7 @@
+            .Case("objc_subscripting", LangOpts.ObjCNonFragileABI)
+            .Case("objc_array_literals", LangOpts.ObjC2)
+            .Case("objc_dictionary_literals", LangOpts.ObjC2)
++           .Case("objc_boxed_expressions", LangOpts.ObjC2)
+            .Case("arc_cf_code_audited", true)
+            // C11 features
+            .Case("c_alignas", LangOpts.C11)
+Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
+===================================================================
+--- lib/StaticAnalyzer/Core/ExprEngine.cpp	(revision 152265)
++++ lib/StaticAnalyzer/Core/ExprEngine.cpp	(working copy)
+@@ -590,7 +590,7 @@
+     case Stmt::ObjCIsaExprClass:
+     case Stmt::ObjCProtocolExprClass:
+     case Stmt::ObjCSelectorExprClass:
+-    case Expr::ObjCNumericLiteralClass:
++    case Expr::ObjCBoxedExprClass:
+     case Stmt::ParenListExprClass:
+     case Stmt::PredefinedExprClass:
+     case Stmt::ShuffleVectorExprClass:
+Index: lib/CodeGen/CGExprScalar.cpp
+===================================================================
+--- lib/CodeGen/CGExprScalar.cpp	(revision 152265)
++++ lib/CodeGen/CGExprScalar.cpp	(working copy)
+@@ -531,8 +531,8 @@
+   Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
+     return CGF.EmitObjCStringLiteral(E);
+   }
+-  Value *VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
+-    return CGF.EmitObjCNumericLiteral(E);
++  Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
++    return CGF.EmitObjCBoxedExpr(E);
+   }
+   Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
+     return CGF.EmitObjCArrayLiteral(E);
+Index: lib/CodeGen/CGObjC.cpp
+===================================================================
+--- lib/CodeGen/CGObjC.cpp	(revision 152265)
++++ lib/CodeGen/CGObjC.cpp	(working copy)
+@@ -51,35 +51,36 @@
+   return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
+ }
+ 
+-/// EmitObjCNumericLiteral - This routine generates code for
+-/// the appropriate +[NSNumber numberWith<Type>:] method.
++/// EmitObjCBoxedExpr - This routine generates code to call
++/// the appropriate expression boxing method. This will either be
++/// one of +[NSNumber numberWith<Type>:], or +[NSString stringWithUTF8String:].
+ ///
+-llvm::Value *CodeGenFunction::EmitObjCNumericLiteral(const ObjCNumericLiteral *E) {
++llvm::Value *
++CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) {
+   // Generate the correct selector for this literal's concrete type.
+-  const Expr *NL = E->getNumber();
++  const Expr *SubExpr = E->getSubExpr();
+   // Get the method.
+-  const ObjCMethodDecl *Method = E->getObjCNumericLiteralMethod();
+-  assert(Method && "NSNumber method is null");
+-  Selector Sel = Method->getSelector();
++  const ObjCMethodDecl *BoxingMethod = E->getBoxingMethod();
++  assert(BoxingMethod && "BoxingMethod is null");
++  assert(BoxingMethod->isClassMethod() && "BoxingMethod must be a class method");
++  Selector Sel = BoxingMethod->getSelector();
+   
+   // Generate a reference to the class pointer, which will be the receiver.
+-  QualType ResultType = E->getType(); // should be NSNumber *
+-  const ObjCObjectPointerType *InterfacePointerType = 
+-    ResultType->getAsObjCInterfacePointerType();
+-  ObjCInterfaceDecl *NSNumberDecl = 
+-    InterfacePointerType->getObjectType()->getInterface();
++  // Assumes that the method was introduced in the class that should be
++  // messaged (avoids pulling it out of the result type).
+   CGObjCRuntime &Runtime = CGM.getObjCRuntime();
+-  llvm::Value *Receiver = Runtime.GetClass(Builder, NSNumberDecl);
+-
+-  const ParmVarDecl *argDecl = *Method->param_begin();
++  const ObjCInterfaceDecl *ClassDecl = BoxingMethod->getClassInterface();
++  llvm::Value *Receiver = Runtime.GetClass(Builder, ClassDecl);
++  
++  const ParmVarDecl *argDecl = *BoxingMethod->param_begin();
+   QualType ArgQT = argDecl->getType().getUnqualifiedType();
+-  RValue RV = EmitAnyExpr(NL);
++  RValue RV = EmitAnyExpr(SubExpr);
+   CallArgList Args;
+   Args.add(RV, ArgQT);
+-
++  
+   RValue result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(), 
+-                                              ResultType, Sel, Receiver, Args, 
+-                                              NSNumberDecl, Method);
++                                              BoxingMethod->getResultType(), Sel, Receiver, Args, 
++                                              ClassDecl, BoxingMethod);
+   return Builder.CreateBitCast(result.getScalarVal(), 
+                                ConvertType(E->getType()));
+ }
+Index: lib/CodeGen/CodeGenTypes.cpp
+===================================================================
+--- lib/CodeGen/CodeGenTypes.cpp	(revision 152265)
++++ lib/CodeGen/CodeGenTypes.cpp	(working copy)
+@@ -133,6 +133,14 @@
+   // when a class is translated, even though they aren't embedded by-value into
+   // the class.
+   if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
++    if (!CRD->hasDefinition() && CRD->hasExternalLexicalStorage()) {
++      ExternalASTSource *EAS = CRD->getASTContext().getExternalSource();
++      if (!EAS)
++        return false;
++      EAS->CompleteType(const_cast<CXXRecordDecl*>(CRD));
++      if (!CRD->hasDefinition())
++        return false;
++    }
+     for (CXXRecordDecl::base_class_const_iterator I = CRD->bases_begin(),
+          E = CRD->bases_end(); I != E; ++I)
+       if (!isSafeToConvert(I->getType()->getAs<RecordType>()->getDecl(),
+Index: lib/CodeGen/CodeGenFunction.h
+===================================================================
+--- lib/CodeGen/CodeGenFunction.h	(revision 152265)
++++ lib/CodeGen/CodeGenFunction.h	(working copy)
+@@ -2238,7 +2238,7 @@
+ 
+   llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
+   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
+-  llvm::Value *EmitObjCNumericLiteral(const ObjCNumericLiteral *E);
++  llvm::Value *EmitObjCBoxedExpr(const ObjCBoxedExpr *E);
+   llvm::Value *EmitObjCArrayLiteral(const ObjCArrayLiteral *E);
+   llvm::Value *EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E);
+   llvm::Value *EmitObjCCollectionLiteral(const Expr *E,
+Index: lib/Parse/ParseObjc.cpp
+===================================================================
+--- lib/Parse/ParseObjc.cpp	(revision 152265)
++++ lib/Parse/ParseObjc.cpp	(working copy)
+@@ -2067,6 +2067,10 @@
+     // Objective-C dictionary literal
+     return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
+           
++  case tok::l_paren:
++    // Objective-C boxed expression
++    return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
++          
+   default:
+     if (Tok.getIdentifierInfo() == 0)
+       return ExprError(Diag(AtLoc, diag::err_unexpected_at));
+@@ -2581,6 +2585,31 @@
+   return Owned(Actions.BuildObjCNumericLiteral(AtLoc, Lit.take()));
+ }
+ 
++/// ParseObjCBoxedExpr -
++/// objc-box-expression:
++///       @( assignment-expression )
++ExprResult
++Parser::ParseObjCBoxedExpr(SourceLocation AtLoc) {
++  if (Tok.isNot(tok::l_paren))
++    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@");
++
++  BalancedDelimiterTracker T(*this, tok::l_paren);
++  T.consumeOpen();
++  ExprResult ValueExpr(ParseAssignmentExpression());
++  if (T.consumeClose())
++    return ExprError();
++
++  if (ValueExpr.isInvalid())
++    return ExprError();
++  
++  // Wrap the sub-expression in a parenthesized expression, to distinguish
++  // a boxed expression from a literal.
++  SourceLocation LPLoc = T.getOpenLocation(), RPLoc = T.getCloseLocation();
++  ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.take());
++  return Owned(Actions.BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc),
++                                          ValueExpr.take()));
++}
++
+ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
+   ExprVector ElementExprs(Actions);                   // array elements.
+   ConsumeBracket(); // consume the l_square.
+Index: lib/Serialization/ASTReaderStmt.cpp
+===================================================================
+--- lib/Serialization/ASTReaderStmt.cpp	(revision 152265)
++++ lib/Serialization/ASTReaderStmt.cpp	(working copy)
+@@ -823,12 +823,12 @@
+   E->setAtLoc(ReadSourceLocation(Record, Idx));
+ }
+ 
+-void ASTStmtReader::VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
++void ASTStmtReader::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
+   VisitExpr(E);
+   // could be one of several IntegerLiteral, FloatLiteral, etc.
+-  E->Number = Reader.ReadSubStmt();
+-  E->ObjCNumericLiteralMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
+-  E->AtLoc = ReadSourceLocation(Record, Idx);
++  E->SubExpr = Reader.ReadSubStmt();
++  E->BoxingMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
++  E->Range = ReadSourceRange(Record, Idx);
+ }
+ 
+ void ASTStmtReader::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
+@@ -1893,8 +1893,8 @@
+     case EXPR_OBJC_STRING_LITERAL:
+       S = new (Context) ObjCStringLiteral(Empty);
+       break;
+-    case EXPR_OBJC_NUMERIC_LITERAL:
+-      S = new (Context) ObjCNumericLiteral(Empty);
++    case EXPR_OBJC_BOXED_EXPRESSION:
++      S = new (Context) ObjCBoxedExpr(Empty);
+       break;
+     case EXPR_OBJC_ARRAY_LITERAL:
+       S = ObjCArrayLiteral::CreateEmpty(Context,
+Index: lib/Serialization/ASTWriter.cpp
+===================================================================
+--- lib/Serialization/ASTWriter.cpp	(revision 152265)
++++ lib/Serialization/ASTWriter.cpp	(working copy)
+@@ -696,7 +696,7 @@
+   RECORD(EXPR_BLOCK_DECL_REF);
+   RECORD(EXPR_GENERIC_SELECTION);
+   RECORD(EXPR_OBJC_STRING_LITERAL);
+-  RECORD(EXPR_OBJC_NUMERIC_LITERAL);
++  RECORD(EXPR_OBJC_BOXED_EXPRESSION);
+   RECORD(EXPR_OBJC_ARRAY_LITERAL);
+   RECORD(EXPR_OBJC_DICTIONARY_LITERAL);
+   RECORD(EXPR_OBJC_ENCODE);
+Index: lib/Serialization/ASTWriterStmt.cpp
+===================================================================
+--- lib/Serialization/ASTWriterStmt.cpp	(revision 152265)
++++ lib/Serialization/ASTWriterStmt.cpp	(working copy)
+@@ -783,12 +783,12 @@
+   Code = serialization::EXPR_OBJC_STRING_LITERAL;
+ }
+ 
+-void ASTStmtWriter::VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
++void ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
+   VisitExpr(E);
+-  Writer.AddStmt(E->getNumber());
+-  Writer.AddDeclRef(E->getObjCNumericLiteralMethod(), Record);
+-  Writer.AddSourceLocation(E->getAtLoc(), Record);
+-  Code = serialization::EXPR_OBJC_NUMERIC_LITERAL;
++  Writer.AddStmt(E->getSubExpr());
++  Writer.AddDeclRef(E->getBoxingMethod(), Record);
++  Writer.AddSourceRange(E->getSourceRange(), Record);
++  Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
+ }
+ 
+ void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {

Removed: lldb/trunk/scripts/clang.check-definition-for-superclasses.diff
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/clang.check-definition-for-superclasses.diff?rev=157025&view=auto
==============================================================================
--- lldb/trunk/scripts/clang.check-definition-for-superclasses.diff (original)
+++ lldb/trunk/scripts/clang.check-definition-for-superclasses.diff (removed)
@@ -1,15 +0,0 @@
-Index: lib/AST/DeclObjC.cpp
-===================================================================
---- lib/AST/DeclObjC.cpp	(revision 152265)
-+++ lib/AST/DeclObjC.cpp	(working copy)
-@@ -330,6 +330,10 @@
-     LoadExternalDefinition();
- 
-   while (ClassDecl != NULL) {
-+    // FIXME: Should make sure no callers ever do this.
-+    if (!ClassDecl->hasDefinition())
-+      return 0;
-+        
-     if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
-       return MethodDecl;
- 

Removed: lldb/trunk/scripts/clang.complete-type-getObjCLayout.diff
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/clang.complete-type-getObjCLayout.diff?rev=157025&view=auto
==============================================================================
--- lldb/trunk/scripts/clang.complete-type-getObjCLayout.diff (original)
+++ lldb/trunk/scripts/clang.complete-type-getObjCLayout.diff (removed)
@@ -1,13 +0,0 @@
-Index: lib/AST/RecordLayoutBuilder.cpp
-===================================================================
---- lib/AST/RecordLayoutBuilder.cpp	(revision 152265)
-+++ lib/AST/RecordLayoutBuilder.cpp	(working copy)
-@@ -2313,6 +2313,8 @@
- ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
-                           const ObjCImplementationDecl *Impl) const {
-   // Retrieve the definition
-+  if (D->hasExternalLexicalStorage() && !D->getDefinition())
-+    getExternalSource()->CompleteType(const_cast<ObjCInterfaceDecl*>(D));
-   D = D->getDefinition();
-   assert(D && D->isThisDeclarationADefinition() && "Invalid interface decl!");
- 

Removed: lldb/trunk/scripts/clang.complete-type-isSafeToConvert.diff
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/clang.complete-type-isSafeToConvert.diff?rev=157025&view=auto
==============================================================================
--- lldb/trunk/scripts/clang.complete-type-isSafeToConvert.diff (original)
+++ lldb/trunk/scripts/clang.complete-type-isSafeToConvert.diff (removed)
@@ -1,19 +0,0 @@
-Index: lib/CodeGen/CodeGenTypes.cpp
-===================================================================
---- lib/CodeGen/CodeGenTypes.cpp	(revision 152265)
-+++ lib/CodeGen/CodeGenTypes.cpp	(working copy)
-@@ -133,6 +133,14 @@
-   // when a class is translated, even though they aren't embedded by-value into
-   // the class.
-   if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
-+    if (!CRD->hasDefinition() && CRD->hasExternalLexicalStorage()) {
-+      ExternalASTSource *EAS = CRD->getASTContext().getExternalSource();
-+      if (!EAS)
-+        return false;
-+      EAS->CompleteType(const_cast<CXXRecordDecl*>(CRD));
-+      if (!CRD->hasDefinition())
-+        return false;
-+    }
-     for (CXXRecordDecl::base_class_const_iterator I = CRD->bases_begin(),
-          E = CRD->bases_end(); I != E; ++I)
-       if (!isSafeToConvert(I->getType()->getAs<RecordType>()->getDecl(),

Removed: lldb/trunk/scripts/clang.decl-printer-reference-type.diff
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/clang.decl-printer-reference-type.diff?rev=157025&view=auto
==============================================================================
--- lldb/trunk/scripts/clang.decl-printer-reference-type.diff (original)
+++ lldb/trunk/scripts/clang.decl-printer-reference-type.diff (removed)
@@ -1,13 +0,0 @@
-Index: lib/AST/DeclPrinter.cpp
-===================================================================
---- lib/AST/DeclPrinter.cpp	(revision 152772)
-+++ lib/AST/DeclPrinter.cpp	(working copy)
-@@ -114,6 +114,8 @@
-       BaseType = FTy->getResultType();
-     else if (const VectorType *VTy = BaseType->getAs<VectorType>())
-       BaseType = VTy->getElementType();
-+    else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>())
-+      BaseType = RTy->getPointeeType();
-     else
-       llvm_unreachable("Unknown declarator!");
-   }

Removed: lldb/trunk/scripts/clang.tail-padded-arrays.diff
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/clang.tail-padded-arrays.diff?rev=157025&view=auto
==============================================================================
--- lldb/trunk/scripts/clang.tail-padded-arrays.diff (original)
+++ lldb/trunk/scripts/clang.tail-padded-arrays.diff (removed)
@@ -1,26 +0,0 @@
-Index: lib/Sema/SemaChecking.cpp
-===================================================================
---- lib/Sema/SemaChecking.cpp	(revision 152265)
-+++ lib/Sema/SemaChecking.cpp	(working copy)
-@@ -4416,12 +4416,16 @@
- 
-   // Don't consider sizes resulting from macro expansions or template argument
-   // substitution to form C89 tail-padded arrays.
--  ConstantArrayTypeLoc TL =
--    cast<ConstantArrayTypeLoc>(FD->getTypeSourceInfo()->getTypeLoc());
--  const Expr *SizeExpr = dyn_cast<IntegerLiteral>(TL.getSizeExpr());
--  if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
--    return false;
- 
-+  TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
-+  if (TInfo) {
-+    ConstantArrayTypeLoc TL =
-+      cast<ConstantArrayTypeLoc>(TInfo->getTypeLoc());
-+    const Expr *SizeExpr = dyn_cast<IntegerLiteral>(TL.getSizeExpr());
-+    if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
-+      return false;
-+  }
-+
-   const RecordDecl *RD = dyn_cast<RecordDecl>(FD->getDeclContext());
-   if (!RD) return false;
-   if (RD->isUnion()) return false;

Removed: lldb/trunk/scripts/clang.template-keyword-fixes.diff
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/clang.template-keyword-fixes.diff?rev=157025&view=auto
==============================================================================
--- lldb/trunk/scripts/clang.template-keyword-fixes.diff (original)
+++ lldb/trunk/scripts/clang.template-keyword-fixes.diff (removed)
@@ -1,13 +0,0 @@
-Index: lib/AST/ExprConstant.cpp
-===================================================================
---- lib/AST/ExprConstant.cpp	(revision 152265)
-+++ lib/AST/ExprConstant.cpp	(working copy)
-@@ -4210,7 +4210,7 @@
- /// character of a string literal.
- template<typename LValue>
- static bool EvaluateBuiltinConstantPForLValue(const LValue &LV) {
--  const Expr *E = LV.getLValueBase().dyn_cast<const Expr*>();
-+  const Expr *E = LV.getLValueBase().template dyn_cast<const Expr*>();
-   return E && isa<StringLiteral>(E) && LV.getLValueOffset().isZero();
- }
- 

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp?rev=157026&r1=157025&r2=157026&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp Thu May 17 18:29:56 2012
@@ -350,10 +350,12 @@
     Target &target(m_process->GetTarget());
     
     static ConstString s_method_signature("-[NSDictionary objectForKeyedSubscript:]");
+    static ConstString s_arclite_method_signature("__arclite_objectForKeyedSubscript");
     
     SymbolContextList sc_list;
     
-    if (target.GetImages().FindSymbolsWithNameAndType(s_method_signature, eSymbolTypeCode, sc_list))
+    if (target.GetImages().FindSymbolsWithNameAndType(s_method_signature, eSymbolTypeCode, sc_list) ||
+        target.GetImages().FindSymbolsWithNameAndType(s_arclite_method_signature, eSymbolTypeCode, sc_list))
         return true;
     else
         return false;

Modified: lldb/trunk/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py?rev=157026&r1=157025&r2=157026&view=diff
==============================================================================
--- lldb/trunk/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py (original)
+++ lldb/trunk/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py Thu May 17 18:29:56 2012
@@ -112,11 +112,15 @@
         self.expect("expr -o -- @1ull", VARIABLES_DISPLAYED_CORRECTLY,
             substrs = ["NSNumber", "1"])
 
-        #<rdar://problem/10924364>
-        #self.expect("expr -o -- @123.45", VARIABLES_DISPLAYED_CORRECTLY,
-        #    substrs = ["NSNumber", "123.45"])
-        #self.expect("expr -o -- @123.45f", VARIABLES_DISPLAYED_CORRECTLY,
-        #    substrs = ["NSNumber", "123.45"])
+        self.expect("expr -o -- @123.45", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["NSNumber", "123.45"])
+        self.expect("expr -o -- @123.45f", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["NSNumber", "123.45"])
+
+        self.expect("expr -o -- @( 1 + 3 )", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["NSNumber", "4"])
+        self.expect("expr -o -- @(\"Hello world\" + 6)", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["NSString", "@\"world\""])
 
             
 if __name__ == '__main__':





More information about the lldb-commits mailing list