aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend/RewriteObjC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/RewriteObjC.cpp')
-rw-r--r--lib/Frontend/RewriteObjC.cpp445
1 files changed, 241 insertions, 204 deletions
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
index 804a5d0b9d..65b57d6b7a 100644
--- a/lib/Frontend/RewriteObjC.cpp
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -1239,11 +1239,26 @@ Stmt *RewriteObjC::RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
// This allows us to handle chain/nested property getters.
Receiver = PropGetters[PRE];
}
- MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
- PDecl->getSetterName(), PDecl->getType(),
- PDecl->getSetterMethodDecl(),
- SourceLocation(), SourceLocation(),
- &ExprVec[0], 1);
+ if (isa<ObjCSuperExpr>(Receiver))
+ MsgExpr = ObjCMessageExpr::Create(*Context,
+ PDecl->getType().getNonReferenceType(),
+ /*FIXME?*/SourceLocation(),
+ Receiver->getLocStart(),
+ /*IsInstanceSuper=*/true,
+ cast<Expr>(Receiver)->getType(),
+ PDecl->getSetterName(),
+ PDecl->getSetterMethodDecl(),
+ &ExprVec[0], 1,
+ /*FIXME:*/SourceLocation());
+ else
+ MsgExpr = ObjCMessageExpr::Create(*Context,
+ PDecl->getType().getNonReferenceType(),
+ /*FIXME: */SourceLocation(),
+ cast<Expr>(Receiver),
+ PDecl->getSetterName(),
+ PDecl->getSetterMethodDecl(),
+ &ExprVec[0], 1,
+ /*FIXME:*/SourceLocation());
Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
// Now do the actual rewrite.
@@ -1268,11 +1283,27 @@ Stmt *RewriteObjC::RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr) {
// This allows us to handle chain/nested property getters.
Receiver = PropGetters[PRE];
}
- MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
- PDecl->getGetterName(), PDecl->getType(),
- PDecl->getGetterMethodDecl(),
- SourceLocation(), SourceLocation(),
- 0, 0);
+
+ if (isa<ObjCSuperExpr>(Receiver))
+ MsgExpr = ObjCMessageExpr::Create(*Context,
+ PDecl->getType().getNonReferenceType(),
+ /*FIXME:*/SourceLocation(),
+ Receiver->getLocStart(),
+ /*IsInstanceSuper=*/true,
+ cast<Expr>(Receiver)->getType(),
+ PDecl->getGetterName(),
+ PDecl->getGetterMethodDecl(),
+ 0, 0,
+ /*FIXME:*/SourceLocation());
+ else
+ MsgExpr = ObjCMessageExpr::Create(*Context,
+ PDecl->getType().getNonReferenceType(),
+ /*FIXME:*/SourceLocation(),
+ cast<Expr>(Receiver),
+ PDecl->getGetterName(),
+ PDecl->getGetterMethodDecl(),
+ 0, 0,
+ /*FIXME:*/SourceLocation());
Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
@@ -2687,205 +2718,211 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
// Synthesize a call to objc_msgSend().
llvm::SmallVector<Expr*, 8> MsgExprs;
- IdentifierInfo *clsName = Exp->getClassName();
-
- // Derive/push the receiver/selector, 2 implicit arguments to objc_msgSend().
- if (clsName) { // class message.
- // FIXME: We need to fix Sema (and the AST for ObjCMessageExpr) to handle
- // the 'super' idiom within a class method.
- if (clsName->getName() == "super") {
- MsgSendFlavor = MsgSendSuperFunctionDecl;
- if (MsgSendStretFlavor)
- MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
- assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
-
- ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
-
- llvm::SmallVector<Expr*, 4> InitExprs;
-
- // set the receiver to self, the first argument to all methods.
- InitExprs.push_back(
- NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
- CastExpr::CK_Unknown,
- new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
- Context->getObjCIdType(),
- SourceLocation()))
- ); // set the 'receiver'.
-
- // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
- llvm::SmallVector<Expr*, 8> ClsExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- ClsExprs.push_back(StringLiteral::Create(*Context,
- ClassDecl->getIdentifier()->getNameStart(),
- ClassDecl->getIdentifier()->getLength(),
- false, argType, SourceLocation()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
- StartLoc,
- EndLoc);
- // (Class)objc_getClass("CurrentClass")
- CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
- Context->getObjCClassType(),
- CastExpr::CK_Unknown, Cls);
- ClsExprs.clear();
- ClsExprs.push_back(ArgExpr);
- Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
- &ClsExprs[0], ClsExprs.size(),
- StartLoc, EndLoc);
-
- // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
- // To turn off a warning, type-cast to 'id'
- InitExprs.push_back( // set 'super class', using class_getSuperclass().
- NoTypeInfoCStyleCastExpr(Context,
- Context->getObjCIdType(),
- CastExpr::CK_Unknown, Cls));
- // struct objc_super
- QualType superType = getSuperStructType();
- Expr *SuperRep;
-
- if (LangOpts.Microsoft) {
- SynthSuperContructorFunctionDecl();
- // Simulate a contructor call...
- DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
- superType, SourceLocation());
- SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
- InitExprs.size(),
- superType, SourceLocation());
- // The code for super is a little tricky to prevent collision with
- // the structure definition in the header. The rewriter has it's own
- // internal definition (__rw_objc_super) that is uses. This is why
- // we need the cast below. For example:
- // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
- //
- SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
- Context->getPointerType(SuperRep->getType()),
- SourceLocation());
- SuperRep = NoTypeInfoCStyleCastExpr(Context,
- Context->getPointerType(superType),
- CastExpr::CK_Unknown, SuperRep);
- } else {
- // (struct objc_super) { <exprs from above> }
- InitListExpr *ILE =
- new (Context) InitListExpr(*Context, SourceLocation(),
- &InitExprs[0], InitExprs.size(),
- SourceLocation());
- TypeSourceInfo *superTInfo
- = Context->getTrivialTypeSourceInfo(superType);
- SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
- superType, ILE, false);
- // struct objc_super *
- SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
- Context->getPointerType(SuperRep->getType()),
- SourceLocation());
- }
- MsgExprs.push_back(SuperRep);
+ switch (Exp->getReceiverKind()) {
+ case ObjCMessageExpr::SuperClass: {
+ MsgSendFlavor = MsgSendSuperFunctionDecl;
+ if (MsgSendStretFlavor)
+ MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+ assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+
+ ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+
+ llvm::SmallVector<Expr*, 4> InitExprs;
+
+ // set the receiver to self, the first argument to all methods.
+ InitExprs.push_back(
+ NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+ CastExpr::CK_Unknown,
+ new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+ Context->getObjCIdType(),
+ SourceLocation()))
+ ); // set the 'receiver'.
+
+ // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+ llvm::SmallVector<Expr*, 8> ClsExprs;
+ QualType argType = Context->getPointerType(Context->CharTy);
+ ClsExprs.push_back(StringLiteral::Create(*Context,
+ ClassDecl->getIdentifier()->getNameStart(),
+ ClassDecl->getIdentifier()->getLength(),
+ false, argType, SourceLocation()));
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
+ &ClsExprs[0],
+ ClsExprs.size(),
+ StartLoc,
+ EndLoc);
+ // (Class)objc_getClass("CurrentClass")
+ CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+ Context->getObjCClassType(),
+ CastExpr::CK_Unknown, Cls);
+ ClsExprs.clear();
+ ClsExprs.push_back(ArgExpr);
+ Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+ &ClsExprs[0], ClsExprs.size(),
+ StartLoc, EndLoc);
+
+ // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+ // To turn off a warning, type-cast to 'id'
+ InitExprs.push_back( // set 'super class', using class_getSuperclass().
+ NoTypeInfoCStyleCastExpr(Context,
+ Context->getObjCIdType(),
+ CastExpr::CK_Unknown, Cls));
+ // struct objc_super
+ QualType superType = getSuperStructType();
+ Expr *SuperRep;
+
+ if (LangOpts.Microsoft) {
+ SynthSuperContructorFunctionDecl();
+ // Simulate a contructor call...
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
+ superType, SourceLocation());
+ SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+ InitExprs.size(),
+ superType, SourceLocation());
+ // The code for super is a little tricky to prevent collision with
+ // the structure definition in the header. The rewriter has it's own
+ // internal definition (__rw_objc_super) that is uses. This is why
+ // we need the cast below. For example:
+ // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+ //
+ SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+ Context->getPointerType(SuperRep->getType()),
+ SourceLocation());
+ SuperRep = NoTypeInfoCStyleCastExpr(Context,
+ Context->getPointerType(superType),
+ CastExpr::CK_Unknown, SuperRep);
} else {
- llvm::SmallVector<Expr*, 8> ClsExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- ClsExprs.push_back(StringLiteral::Create(*Context,
- clsName->getNameStart(),
- clsName->getLength(),
- false, argType,
- SourceLocation()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
- StartLoc, EndLoc);
- MsgExprs.push_back(Cls);
+ // (struct objc_super) { <exprs from above> }
+ InitListExpr *ILE =
+ new (Context) InitListExpr(*Context, SourceLocation(),
+ &InitExprs[0], InitExprs.size(),
+ SourceLocation());
+ TypeSourceInfo *superTInfo
+ = Context->getTrivialTypeSourceInfo(superType);
+ SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+ superType, ILE, false);
+ // struct objc_super *
+ SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+ Context->getPointerType(SuperRep->getType()),
+ SourceLocation());
}
- } else { // instance message.
- Expr *recExpr = Exp->getReceiver();
-
- if (isSuperReceiver(recExpr)) {
- MsgSendFlavor = MsgSendSuperFunctionDecl;
- if (MsgSendStretFlavor)
- MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
- assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
- ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
- llvm::SmallVector<Expr*, 4> InitExprs;
-
- InitExprs.push_back(
- NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
- CastExpr::CK_Unknown,
- new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
- Context->getObjCIdType(),
- SourceLocation()))
- ); // set the 'receiver'.
-
- // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
- llvm::SmallVector<Expr*, 8> ClsExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- ClsExprs.push_back(StringLiteral::Create(*Context,
- ClassDecl->getIdentifier()->getNameStart(),
- ClassDecl->getIdentifier()->getLength(),
- false, argType, SourceLocation()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
- StartLoc, EndLoc);
- // (Class)objc_getClass("CurrentClass")
- CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
- Context->getObjCClassType(),
- CastExpr::CK_Unknown, Cls);
- ClsExprs.clear();
- ClsExprs.push_back(ArgExpr);
- Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
- &ClsExprs[0], ClsExprs.size(),
- StartLoc, EndLoc);
-
- // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
- // To turn off a warning, type-cast to 'id'
- InitExprs.push_back(
- // set 'super class', using class_getSuperclass().
- NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
- CastExpr::CK_Unknown, Cls));
- // struct objc_super
- QualType superType = getSuperStructType();
- Expr *SuperRep;
-
- if (LangOpts.Microsoft) {
- SynthSuperContructorFunctionDecl();
- // Simulate a contructor call...
- DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
- superType, SourceLocation());
- SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
- InitExprs.size(),
- superType, SourceLocation());
- // The code for super is a little tricky to prevent collision with
- // the structure definition in the header. The rewriter has it's own
- // internal definition (__rw_objc_super) that is uses. This is why
- // we need the cast below. For example:
- // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
- //
- SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
- Context->getPointerType(SuperRep->getType()),
- SourceLocation());
- SuperRep = NoTypeInfoCStyleCastExpr(Context,
- Context->getPointerType(superType),
- CastExpr::CK_Unknown, SuperRep);
- } else {
- // (struct objc_super) { <exprs from above> }
- InitListExpr *ILE =
- new (Context) InitListExpr(*Context, SourceLocation(),
- &InitExprs[0], InitExprs.size(),
- SourceLocation());
- TypeSourceInfo *superTInfo
- = Context->getTrivialTypeSourceInfo(superType);
- SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
- superType, ILE, false);
- }
- MsgExprs.push_back(SuperRep);
+ MsgExprs.push_back(SuperRep);
+ break;
+ }
+
+ case ObjCMessageExpr::Class: {
+ llvm::SmallVector<Expr*, 8> ClsExprs;
+ QualType argType = Context->getPointerType(Context->CharTy);
+ ObjCInterfaceDecl *Class
+ = Exp->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+ IdentifierInfo *clsName = Class->getIdentifier();
+ ClsExprs.push_back(StringLiteral::Create(*Context,
+ clsName->getNameStart(),
+ clsName->getLength(),
+ false, argType,
+ SourceLocation()));
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+ &ClsExprs[0],
+ ClsExprs.size(),
+ StartLoc, EndLoc);
+ MsgExprs.push_back(Cls);
+ break;
+ }
+
+ case ObjCMessageExpr::SuperInstance:{
+ MsgSendFlavor = MsgSendSuperFunctionDecl;
+ if (MsgSendStretFlavor)
+ MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+ assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+ ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+ llvm::SmallVector<Expr*, 4> InitExprs;
+
+ InitExprs.push_back(
+ NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+ CastExpr::CK_Unknown,
+ new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+ Context->getObjCIdType(),
+ SourceLocation()))
+ ); // set the 'receiver'.
+
+ // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+ llvm::SmallVector<Expr*, 8> ClsExprs;
+ QualType argType = Context->getPointerType(Context->CharTy);
+ ClsExprs.push_back(StringLiteral::Create(*Context,
+ ClassDecl->getIdentifier()->getNameStart(),
+ ClassDecl->getIdentifier()->getLength(),
+ false, argType, SourceLocation()));
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+ &ClsExprs[0],
+ ClsExprs.size(),
+ StartLoc, EndLoc);
+ // (Class)objc_getClass("CurrentClass")
+ CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+ Context->getObjCClassType(),
+ CastExpr::CK_Unknown, Cls);
+ ClsExprs.clear();
+ ClsExprs.push_back(ArgExpr);
+ Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+ &ClsExprs[0], ClsExprs.size(),
+ StartLoc, EndLoc);
+
+ // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+ // To turn off a warning, type-cast to 'id'
+ InitExprs.push_back(
+ // set 'super class', using class_getSuperclass().
+ NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+ CastExpr::CK_Unknown, Cls));
+ // struct objc_super
+ QualType superType = getSuperStructType();
+ Expr *SuperRep;
+
+ if (LangOpts.Microsoft) {
+ SynthSuperContructorFunctionDecl();
+ // Simulate a contructor call...
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
+ superType, SourceLocation());
+ SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+ InitExprs.size(),
+ superType, SourceLocation());
+ // The code for super is a little tricky to prevent collision with
+ // the structure definition in the header. The rewriter has it's own
+ // internal definition (__rw_objc_super) that is uses. This is why
+ // we need the cast below. For example:
+ // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+ //
+ SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+ Context->getPointerType(SuperRep->getType()),
+ SourceLocation());
+ SuperRep = NoTypeInfoCStyleCastExpr(Context,
+ Context->getPointerType(superType),
+ CastExpr::CK_Unknown, SuperRep);
} else {
- // Remove all type-casts because it may contain objc-style types; e.g.
- // Foo<Proto> *.
- while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
- recExpr = CE->getSubExpr();
- recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
- CastExpr::CK_Unknown, recExpr);
- MsgExprs.push_back(recExpr);
+ // (struct objc_super) { <exprs from above> }
+ InitListExpr *ILE =
+ new (Context) InitListExpr(*Context, SourceLocation(),
+ &InitExprs[0], InitExprs.size(),
+ SourceLocation());
+ TypeSourceInfo *superTInfo
+ = Context->getTrivialTypeSourceInfo(superType);
+ SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+ superType, ILE, false);
}
+ MsgExprs.push_back(SuperRep);
+ break;
+ }
+
+ case ObjCMessageExpr::Instance: {
+ // Remove all type-casts because it may contain objc-style types; e.g.
+ // Foo<Proto> *.
+ Expr *recExpr = Exp->getInstanceReceiver();
+ while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
+ recExpr = CE->getSubExpr();
+ recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+ CastExpr::CK_Unknown, recExpr);
+ MsgExprs.push_back(recExpr);
+ break;
+ }
}
+
// Create a call to sel_registerName("selName"), it will be the 2nd argument.
llvm::SmallVector<Expr*, 8> SelExprs;
QualType argType = Context->getPointerType(Context->CharTy);