diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2010-03-10 21:17:41 +0000 | 
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-03-10 21:17:41 +0000 | 
| commit | a4a925febb024fbe8ab65ca2625d7165945ce050 (patch) | |
| tree | f8f344723415584983ed30722e8277af88011c9a /clang | |
| parent | c9d4a84c2a9b35d1ea6739205f735c809661c526 (diff) | |
| download | bcm5719-llvm-a4a925febb024fbe8ab65ca2625d7165945ce050.tar.gz bcm5719-llvm-a4a925febb024fbe8ab65ca2625d7165945ce050.zip  | |
Change the 'super' messaging API in the rewriter.
Fixes radar 7738452.
llvm-svn: 98190
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Frontend/RewriteObjC.cpp | 85 | ||||
| -rw-r--r-- | clang/test/Rewriter/rewrite-super-message.mm | 20 | 
2 files changed, 82 insertions, 23 deletions
diff --git a/clang/lib/Frontend/RewriteObjC.cpp b/clang/lib/Frontend/RewriteObjC.cpp index 378b4225c53..a3a30e2390f 100644 --- a/clang/lib/Frontend/RewriteObjC.cpp +++ b/clang/lib/Frontend/RewriteObjC.cpp @@ -89,6 +89,7 @@ namespace {      FunctionDecl *MsgSendFpretFunctionDecl;      FunctionDecl *GetClassFunctionDecl;      FunctionDecl *GetMetaClassFunctionDecl; +    FunctionDecl *GetSuperClassFunctionDecl;      FunctionDecl *SelGetUidFunctionDecl;      FunctionDecl *CFStringFunctionDecl;      FunctionDecl *SuperContructorFunctionDecl; @@ -271,7 +272,7 @@ namespace {      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 @@ namespace {      void SynthMsgSendSuperStretFunctionDecl();      void SynthGetClassFunctionDecl();      void SynthGetMetaClassFunctionDecl(); +    void SynthGetSuperClassFunctionDecl();      void SynthSelGetUidFunctionDecl();      void SynthSuperContructorFunctionDecl(); @@ -510,6 +512,7 @@ void RewriteObjC::Initialize(ASTContext &context) {    MsgSendFpretFunctionDecl = 0;    GetClassFunctionDecl = 0;    GetMetaClassFunctionDecl = 0; +  GetSuperClassFunctionDecl = 0;    SelGetUidFunctionDecl = 0;    CFStringFunctionDecl = 0;    ConstantStringClassReference = 0; @@ -572,6 +575,8 @@ void RewriteObjC::Initialize(ASTContext &context) {    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 @@ void RewriteObjC::SynthGetClassFunctionDecl() {                                            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 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {    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 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,      SynthMsgSendFpretFunctionDecl();    if (!GetClassFunctionDecl)      SynthGetClassFunctionDecl(); +  if (!GetSuperClassFunctionDecl) +    SynthGetSuperClassFunctionDecl();    if (!GetMetaClassFunctionDecl)      SynthGetMetaClassFunctionDecl(); @@ -2669,8 +2685,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,          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 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,                                       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 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,    } 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 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,                                       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 diff --git a/clang/test/Rewriter/rewrite-super-message.mm b/clang/test/Rewriter/rewrite-super-message.mm new file mode 100644 index 00000000000..036aa1bb318 --- /dev/null +++ b/clang/test/Rewriter/rewrite-super-message.mm @@ -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 *); + +@interface __NSCFType +@end + +@interface __NSCFString : __NSCFType +- (const char *)UTF8String; +@end + +@implementation __NSCFString +- (const char *)UTF8String { +    return (const char *)[super UTF8String]; +} +@end + +// CHECK: call %struct.objc_class* @class_getSuperclass  | 

