aboutsummaryrefslogtreecommitdiff
path: root/lib/Rewrite/RewriteModernObjC.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2012-04-06 19:47:36 +0000
committerFariborz Jahanian <fjahanian@apple.com>2012-04-06 19:47:36 +0000
commitb0f245ccce94a069c9334e51f3c5d502eb2d0215 (patch)
tree15cf8b281e1666027e08be2e984b3cfdb712c3a4 /lib/Rewrite/RewriteModernObjC.cpp
parent5f0a1c12dacadd5a061ea5b57d51cf6798ae22a1 (diff)
modern objective-c translator: translate array literal
expressions. // rdar://10803676 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154196 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Rewrite/RewriteModernObjC.cpp')
-rw-r--r--lib/Rewrite/RewriteModernObjC.cpp82
1 files changed, 67 insertions, 15 deletions
diff --git a/lib/Rewrite/RewriteModernObjC.cpp b/lib/Rewrite/RewriteModernObjC.cpp
index e160f0f434..0c57ae0812 100644
--- a/lib/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Rewrite/RewriteModernObjC.cpp
@@ -2608,6 +2608,48 @@ Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
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 @@ Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
StartLoc, EndLoc);
MsgExprs.push_back(SelExp);
- unsigned NumElements = Exp->getNumElements();
+ // (const id [])objects
+ MsgExprs.push_back(ArrayLiteralObjects);
- // 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));
-
- 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 @@ void RewriteModernObjC::Initialize(ASTContext &context) {
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";