@@ -367,6 +367,13 @@ namespace {
367
367
Expr **args, unsigned nargs,
368
368
SourceLocation StartLoc=SourceLocation(),
369
369
SourceLocation EndLoc=SourceLocation());
370
+
371
+ Expr *SynthMsgSendStretCallExpr (FunctionDecl *MsgSendStretFlavor,
372
+ QualType msgSendType,
373
+ QualType returnType,
374
+ SmallVectorImpl<QualType> &ArgTypes,
375
+ SmallVectorImpl<Expr*> &MsgExprs,
376
+ ObjCMethodDecl *Method);
370
377
371
378
Stmt *SynthMessageExpr (ObjCMessageExpr *Exp,
372
379
SourceLocation StartLoc=SourceLocation(),
@@ -3055,6 +3062,107 @@ QualType RewriteModernObjC::getConstantStringStructType() {
3055
3062
return Context->getTagDeclType (ConstantStringDecl);
3056
3063
}
3057
3064
3065
+ // / getFunctionSourceLocation - returns start location of a function
3066
+ // / definition. Complication arises when function has declared as
3067
+ // / extern "C" or extern "C" {...}
3068
+ static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
3069
+ FunctionDecl *FD) {
3070
+ if (FD->isExternC () && !FD->isMain ()) {
3071
+ const DeclContext *DC = FD->getDeclContext ();
3072
+ if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC))
3073
+ // if it is extern "C" {...}, return function decl's own location.
3074
+ if (!LSD->getRBraceLoc ().isValid ())
3075
+ return LSD->getExternLoc ();
3076
+ }
3077
+ if (FD->getStorageClassAsWritten () != SC_None)
3078
+ R.RewriteBlockLiteralFunctionDecl (FD);
3079
+ return FD->getTypeSpecStartLoc ();
3080
+ }
3081
+
3082
+ // / SynthMsgSendStretCallExpr - This routine translates message expression
3083
+ // / into a call to objc_msgSend_stret() entry point. Tricky part is that
3084
+ // / nil check on receiver must be performed before calling objc_msgSend_stret.
3085
+ // / MsgSendStretFlavor - function declaration objc_msgSend_stret(...)
3086
+ // / msgSendType - function type of objc_msgSend_stret(...)
3087
+ // / returnType - Result type of the method being synthesized.
3088
+ // / ArgTypes - type of the arguments passed to objc_msgSend_stret, starting with receiver type.
3089
+ // / MsgExprs - list of argument expressions being passed to objc_msgSend_stret,
3090
+ // / starting with receiver.
3091
+ // / Method - Method being rewritten.
3092
+ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr (FunctionDecl *MsgSendStretFlavor,
3093
+ QualType msgSendType,
3094
+ QualType returnType,
3095
+ SmallVectorImpl<QualType> &ArgTypes,
3096
+ SmallVectorImpl<Expr*> &MsgExprs,
3097
+ ObjCMethodDecl *Method) {
3098
+ // Now do the "normal" pointer to function cast.
3099
+ QualType castType = getSimpleFunctionType (returnType, &ArgTypes[0 ], ArgTypes.size (),
3100
+ Method ? Method->isVariadic () : false );
3101
+ castType = Context->getPointerType (castType);
3102
+
3103
+ // build type for containing the objc_msgSend_stret object.
3104
+ static unsigned stretCount=0 ;
3105
+ std::string name = " __Stret" ; name += utostr (stretCount);
3106
+ std::string str = " struct " ; str += name;
3107
+ str += " {\n\t " ;
3108
+ str += name;
3109
+ str += " (id receiver, SEL sel" ;
3110
+ for (unsigned i = 2 ; i < ArgTypes.size (); i++) {
3111
+ str += " , " ; str += ArgTypes[i].getAsString (Context->getPrintingPolicy ());
3112
+ str += " arg" ; str += utostr (i);
3113
+ }
3114
+ // could be vararg.
3115
+ for (unsigned i = ArgTypes.size (); i < MsgExprs.size (); i++) {
3116
+ str += " , " ; str += MsgExprs[i]->getType ().getAsString (Context->getPrintingPolicy ());
3117
+ str += " arg" ; str += utostr (i);
3118
+ }
3119
+
3120
+ str += " ) {\n " ;
3121
+ str += " \t if (receiver == 0)\n " ;
3122
+ str += " \t memset((void*)&s, 0, sizeof(s));\n " ;
3123
+ str += " \t else\n " ;
3124
+ str += " \t s = ((" ; str += castType.getAsString (Context->getPrintingPolicy ());
3125
+ str += " )(void *)objc_msgSend_stret)(receiver, sel" ;
3126
+ for (unsigned i = 2 ; i < ArgTypes.size (); i++) {
3127
+ str += " , arg" ; str += utostr (i);
3128
+ }
3129
+ // could be vararg.
3130
+ for (unsigned i = ArgTypes.size (); i < MsgExprs.size (); i++) {
3131
+ str += " , arg" ; str += utostr (i);
3132
+ }
3133
+
3134
+ str += " );\n " ;
3135
+ str += " \t }\n " ;
3136
+ str += " \t " ; str += returnType.getAsString (Context->getPrintingPolicy ());
3137
+ str += " s;\n " ;
3138
+ str += " };\n\n " ;
3139
+ SourceLocation FunLocStart = getFunctionSourceLocation (*this , CurFunctionDef);
3140
+ InsertText (FunLocStart, str);
3141
+ ++stretCount;
3142
+
3143
+ // AST for __Stretn(receiver, args).s;
3144
+ IdentifierInfo *ID = &Context->Idents .get (name);
3145
+ FunctionDecl *FD = FunctionDecl::Create (*Context, TUDecl, SourceLocation (),
3146
+ SourceLocation (), ID, castType, 0 , SC_Extern,
3147
+ SC_None, false , false );
3148
+ DeclRefExpr *DRE = new (Context) DeclRefExpr (FD, false , castType, VK_RValue,
3149
+ SourceLocation ());
3150
+ CallExpr *STCE = new (Context) CallExpr (*Context, DRE, &MsgExprs[0 ], MsgExprs.size (),
3151
+ castType, VK_LValue, SourceLocation ());
3152
+
3153
+ FieldDecl *FieldD = FieldDecl::Create (*Context, 0 , SourceLocation (),
3154
+ SourceLocation (),
3155
+ &Context->Idents .get (" s" ),
3156
+ returnType, 0 ,
3157
+ /* BitWidth=*/ 0 , /* Mutable=*/ true ,
3158
+ ICIS_NoInit);
3159
+ MemberExpr *ME = new (Context) MemberExpr (STCE, false , FieldD, SourceLocation (),
3160
+ FieldD->getType (), VK_LValue,
3161
+ OK_Ordinary);
3162
+
3163
+ return ME;
3164
+ }
3165
+
3058
3166
Stmt *RewriteModernObjC::SynthMessageExpr (ObjCMessageExpr *Exp,
3059
3167
SourceLocation StartLoc,
3060
3168
SourceLocation EndLoc) {
@@ -3443,29 +3551,10 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
3443
3551
// expression which dictate which one to envoke depending on size of
3444
3552
// method's return type.
3445
3553
3446
- // Create a reference to the objc_msgSend_stret() declaration.
3447
- DeclRefExpr *STDRE = new (Context) DeclRefExpr (MsgSendStretFlavor,
3448
- false , msgSendType,
3449
- VK_LValue, SourceLocation ());
3450
- // Need to cast objc_msgSend_stret to "void *" (see above comment).
3451
- cast = NoTypeInfoCStyleCastExpr (Context,
3452
- Context->getPointerType (Context->VoidTy ),
3453
- CK_BitCast, STDRE);
3454
- // Now do the "normal" pointer to function cast.
3455
- castType = getSimpleFunctionType (returnType, &ArgTypes[0 ], ArgTypes.size (),
3456
- Exp->getMethodDecl () ? Exp->getMethodDecl ()->isVariadic () : false );
3457
- castType = Context->getPointerType (castType);
3458
- cast = NoTypeInfoCStyleCastExpr (Context, castType, CK_BitCast,
3459
- cast);
3460
-
3461
- // Don't forget the parens to enforce the proper binding.
3462
- PE = new (Context) ParenExpr (SourceLocation (), SourceLocation (), cast);
3463
-
3464
- FT = msgSendType->getAs <FunctionType>();
3465
- CallExpr *STCE = new (Context) CallExpr (*Context, PE, &MsgExprs[0 ],
3466
- MsgExprs.size (),
3467
- FT->getResultType (), VK_RValue,
3468
- SourceLocation ());
3554
+ Expr *STCE = SynthMsgSendStretCallExpr (MsgSendStretFlavor,
3555
+ msgSendType, returnType,
3556
+ ArgTypes, MsgExprs,
3557
+ Exp->getMethodDecl ());
3469
3558
3470
3559
// Build sizeof(returnType)
3471
3560
UnaryExprOrTypeTraitExpr *sizeofExpr =
@@ -4152,23 +4241,6 @@ std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag,
4152
4241
return S;
4153
4242
}
4154
4243
4155
- // / getFunctionSourceLocation - returns start location of a function
4156
- // / definition. Complication arises when function has declared as
4157
- // / extern "C" or extern "C" {...}
4158
- static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
4159
- FunctionDecl *FD) {
4160
- if (FD->isExternC () && !FD->isMain ()) {
4161
- const DeclContext *DC = FD->getDeclContext ();
4162
- if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC))
4163
- // if it is extern "C" {...}, return function decl's own location.
4164
- if (!LSD->getRBraceLoc ().isValid ())
4165
- return LSD->getExternLoc ();
4166
- }
4167
- if (FD->getStorageClassAsWritten () != SC_None)
4168
- R.RewriteBlockLiteralFunctionDecl (FD);
4169
- return FD->getTypeSpecStartLoc ();
4170
- }
4171
-
4172
4244
void RewriteModernObjC::SynthesizeBlockLiterals (SourceLocation FunLocStart,
4173
4245
StringRef FunName) {
4174
4246
bool RewriteSC = (GlobalVarDecl &&
@@ -5885,6 +5957,9 @@ void RewriteModernObjC::Initialize(ASTContext &context) {
5885
5957
Preamble += " #define __weak\n " ;
5886
5958
}
5887
5959
5960
+ // needed for use of memset.
5961
+ Preamble += " \n #include <string.h>\n " ;
5962
+
5888
5963
// Declarations required for modern objective-c array and dictionary literals.
5889
5964
Preamble += " \n #include <stdarg.h>\n " ;
5890
5965
Preamble += " struct __NSContainer_literal {\n " ;
0 commit comments