[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