[cfe-commits] r154196 - in /cfe/trunk: lib/Rewrite/RewriteModernObjC.cpp test/Rewriter/rewrite-modern-array-literal.mm

Fariborz Jahanian fjahanian at apple.com
Fri Apr 6 12:47:36 PDT 2012


Author: fjahanian
Date: Fri Apr  6 14:47:36 2012
New Revision: 154196

URL: http://llvm.org/viewvc/llvm-project?rev=154196&view=rev
Log:
modern objective-c translator: translate array literal
expressions. // rdar://10803676

Added:
    cfe/trunk/test/Rewriter/rewrite-modern-array-literal.mm
Modified:
    cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp

Modified: cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp?rev=154196&r1=154195&r2=154196&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp Fri Apr  6 14:47:36 2012
@@ -2608,6 +2608,48 @@
   SourceLocation StartLoc = Exp->getLocStart();
   SourceLocation EndLoc = Exp->getLocEnd();
   
+  // Build the expression: __NSArray_literal(int, ...).arr
+  QualType IntQT = Context->IntTy;
+  QualType NSArrayFType =
+    getSimpleFunctionType(Context->VoidTy, &IntQT, 1, true);
+  std::string NSArrayFName("__NSArray_literal");
+  FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
+  DeclRefExpr *NSArrayDRE = 
+    new (Context) DeclRefExpr(NSArrayFD, false, 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;
@@ -2642,22 +2684,14 @@
                                                   StartLoc, EndLoc);
   MsgExprs.push_back(SelExp);
   
-  unsigned NumElements = Exp->getNumElements();
-  
-  // FIXME. Incomplete.
-  InitListExpr *ILE =
-    new (Context) InitListExpr(*Context, SourceLocation(),
-                               Exp->getElements(), NumElements,
-                               SourceLocation());
-  MsgExprs.push_back(ILE);
-  unsigned UnsignedIntSize = 
-    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
+  // (const id [])objects
+  MsgExprs.push_back(ArrayLiteralObjects);
   
-  Expr *count = IntegerLiteral::Create(*Context,
-                                       llvm::APInt(UnsignedIntSize, NumElements),
-                                       Context->UnsignedIntTy,
-                                       SourceLocation());
-  MsgExprs.push_back(count);
+  // (NSUInteger)cnt
+  Expr *cnt = IntegerLiteral::Create(*Context,
+                                     llvm::APInt(UnsignedIntSize, NumElements),
+                                     Context->UnsignedIntTy, SourceLocation());
+  MsgExprs.push_back(cnt);
   
   
   SmallVector<QualType, 4> ArgTypes;
@@ -5477,6 +5511,24 @@
     Preamble += "#define __block\n";
     Preamble += "#define __weak\n";
   }
+  
+  // Declarations required for modern objective-c array and dictionary literals.
+  Preamble += "\n#include <stdarg.h>\n";
+  Preamble += "struct __NSArray_literal {\n";
+  Preamble += "  void * *arr;\n";
+  Preamble += "  __NSArray_literal (unsigned int count, ...) {\n";
+  Preamble += "\tva_list marker;\n";
+  Preamble += "\tva_start(marker, count);\n";
+  Preamble += "\tarr = new void *[count];\n";
+  Preamble += "\tfor (unsigned i = 0; i < count; i++)\n";
+  Preamble += "\t  arr[i] = va_arg(marker, void *);\n";
+  Preamble += "\tva_end( marker );\n";
+  Preamble += "  };\n";
+  Preamble += "  ~__NSArray_literal() {\n";
+  Preamble += "\tdelete[] arr;\n";
+  Preamble += "  }\n";
+  Preamble += "};\n";
+  
   // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
   // as this avoids warning in any 64bit/32bit compilation model.
   Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";

Added: cfe/trunk/test/Rewriter/rewrite-modern-array-literal.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-modern-array-literal.mm?rev=154196&view=auto
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-modern-array-literal.mm (added)
+++ cfe/trunk/test/Rewriter/rewrite-modern-array-literal.mm Fri Apr  6 14:47:36 2012
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -x objective-c++ -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// rdar://10803676
+
+extern "C" void *sel_registerName(const char *);
+ at class NSString;
+
+ at interface NSNumber
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithInt:(int)value;
+ at end
+
+typedef unsigned long NSUInteger;
+
+ at interface NSArray 
++ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
+ at end
+
+int i;
+int main() {
+  NSArray *array = @[ @"Hello", @1234 ];
+  if (i) {
+    NSArray *array = @[ @"Hello", @1234 ];
+  }
+  NSArray *array1 = @[ @"Hello", @1234, @[ @"Hello", @1234 ] ];
+}
+





More information about the cfe-commits mailing list