[cfe-commits] r98190 - in /cfe/trunk: lib/Frontend/RewriteObjC.cpp test/Rewriter/rewrite-super-message.mm
Fariborz Jahanian
fjahanian at apple.com
Wed Mar 10 13:17:41 PST 2010
Author: fjahanian
Date: Wed Mar 10 15:17:41 2010
New Revision: 98190
URL: http://llvm.org/viewvc/llvm-project?rev=98190&view=rev
Log:
Change the 'super' messaging API in the rewriter.
Fixes radar 7738452.
Added:
cfe/trunk/test/Rewriter/rewrite-super-message.mm
Modified:
cfe/trunk/lib/Frontend/RewriteObjC.cpp
Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=98190&r1=98189&r2=98190&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Wed Mar 10 15:17:41 2010
@@ -89,6 +89,7 @@
FunctionDecl *MsgSendFpretFunctionDecl;
FunctionDecl *GetClassFunctionDecl;
FunctionDecl *GetMetaClassFunctionDecl;
+ FunctionDecl *GetSuperClassFunctionDecl;
FunctionDecl *SelGetUidFunctionDecl;
FunctionDecl *CFStringFunctionDecl;
FunctionDecl *SuperContructorFunctionDecl;
@@ -271,7 +272,7 @@
void RewriteTypeOfDecl(VarDecl *VD);
void RewriteObjCQualifiedInterfaceTypes(Expr *E);
bool needToScanForQualifiers(QualType T);
- ObjCInterfaceDecl *isSuperReceiver(Expr *recExpr);
+ bool isSuperReceiver(Expr *recExpr);
QualType getSuperStructType();
QualType getConstantStringStructType();
bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
@@ -323,6 +324,7 @@
void SynthMsgSendSuperStretFunctionDecl();
void SynthGetClassFunctionDecl();
void SynthGetMetaClassFunctionDecl();
+ void SynthGetSuperClassFunctionDecl();
void SynthSelGetUidFunctionDecl();
void SynthSuperContructorFunctionDecl();
@@ -510,6 +512,7 @@
MsgSendFpretFunctionDecl = 0;
GetClassFunctionDecl = 0;
GetMetaClassFunctionDecl = 0;
+ GetSuperClassFunctionDecl = 0;
SelGetUidFunctionDecl = 0;
CFStringFunctionDecl = 0;
ConstantStringClassReference = 0;
@@ -572,6 +575,8 @@
Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass";
Preamble += "(const char *);\n";
+ Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
+ Preamble += "(struct objc_class *);\n";
Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
Preamble += "(const char *);\n";
Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
@@ -2491,6 +2496,23 @@
FunctionDecl::Extern, false);
}
+// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
+void RewriteObjC::SynthGetSuperClassFunctionDecl() {
+ IdentifierInfo *getSuperClassIdent =
+ &Context->Idents.get("class_getSuperclass");
+ llvm::SmallVector<QualType, 16> ArgTys;
+ ArgTys.push_back(Context->getObjCClassType());
+ QualType getClassType = Context->getFunctionType(Context->getObjCClassType(),
+ &ArgTys[0], ArgTys.size(),
+ false /*isVariadic*/, 0,
+ false, false, 0, 0, false,
+ CC_Default);
+ GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+ SourceLocation(),
+ getSuperClassIdent, getClassType, 0,
+ FunctionDecl::Extern, false);
+}
+
// SynthGetMetaClassFunctionDecl - id objc_getClass(const char *name);
void RewriteObjC::SynthGetMetaClassFunctionDecl() {
IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
@@ -2551,18 +2573,10 @@
return cast;
}
-ObjCInterfaceDecl *RewriteObjC::isSuperReceiver(Expr *recExpr) {
+bool RewriteObjC::isSuperReceiver(Expr *recExpr) {
// check if we are sending a message to 'super'
- if (!CurMethodDef || !CurMethodDef->isInstanceMethod()) return 0;
-
- if (ObjCSuperExpr *Super = dyn_cast<ObjCSuperExpr>(recExpr)) {
- const ObjCObjectPointerType *OPT =
- Super->getType()->getAs<ObjCObjectPointerType>();
- assert(OPT);
- const ObjCInterfaceType *IT = OPT->getInterfaceType();
- return IT->getDecl();
- }
- return 0;
+ if (!CurMethodDef || !CurMethodDef->isInstanceMethod()) return false;
+ return isa<ObjCSuperExpr>(recExpr);
}
// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
@@ -2640,6 +2654,8 @@
SynthMsgSendFpretFunctionDecl();
if (!GetClassFunctionDecl)
SynthGetClassFunctionDecl();
+ if (!GetSuperClassFunctionDecl)
+ SynthGetSuperClassFunctionDecl();
if (!GetMetaClassFunctionDecl)
SynthGetMetaClassFunctionDecl();
@@ -2669,8 +2685,7 @@
MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
- ObjCInterfaceDecl *SuperDecl =
- CurMethodDef->getClassInterface()->getSuperClass();
+ ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
llvm::SmallVector<Expr*, 4> InitExprs;
@@ -2683,19 +2698,31 @@
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,
- SuperDecl->getIdentifier()->getNameStart(),
- SuperDecl->getIdentifier()->getLength(),
+ 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 objc_getClass().
+ InitExprs.push_back( // set 'super class', using class_getSuperclass().
NoTypeInfoCStyleCastExpr(Context,
Context->getObjCIdType(),
CastExpr::CK_Unknown, Cls));
@@ -2755,12 +2782,12 @@
} else { // instance message.
Expr *recExpr = Exp->getReceiver();
- if (ObjCInterfaceDecl *SuperDecl = isSuperReceiver(recExpr)) {
+ 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(
@@ -2770,20 +2797,32 @@
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,
- SuperDecl->getIdentifier()->getNameStart(),
- SuperDecl->getIdentifier()->getLength(),
+ 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 objc_getClass().
+ // set 'super class', using class_getSuperclass().
NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
CastExpr::CK_Unknown, Cls));
// struct objc_super
Added: cfe/trunk/test/Rewriter/rewrite-super-message.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-super-message.mm?rev=98190&view=auto
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-super-message.mm (added)
+++ cfe/trunk/test/Rewriter/rewrite-super-message.mm Wed Mar 10 15:17:41 2010
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"id=struct objc_object *" -D"Class=struct objc_class *" -D"SEL=void*" -D"__declspec(X)=" -emit-llvm -o - %t-rw.cpp | FileCheck %t-rw.cpp
+// radar 7738453
+
+void *sel_registerName(const char *);
+
+ at interface __NSCFType
+ at end
+
+ at interface __NSCFString : __NSCFType
+- (const char *)UTF8String;
+ at end
+
+ at implementation __NSCFString
+- (const char *)UTF8String {
+ return (const char *)[super UTF8String];
+}
+ at end
+
+// CHECK: call %struct.objc_class* @class_getSuperclass
More information about the cfe-commits
mailing list