mirror of https://github.com/microsoft/clang.git
Modern ObjectiveC translator. Fix translation of
message sent to aggregate-valued methods. Fix visibility of trampoline type used in translation of such expressions. // rdar://14932320 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190341 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9522ae1330
commit
426bb9c900
|
@ -411,7 +411,6 @@ namespace {
|
||||||
SourceLocation EndLoc=SourceLocation());
|
SourceLocation EndLoc=SourceLocation());
|
||||||
|
|
||||||
Expr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
|
Expr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
|
||||||
QualType msgSendType,
|
|
||||||
QualType returnType,
|
QualType returnType,
|
||||||
SmallVectorImpl<QualType> &ArgTypes,
|
SmallVectorImpl<QualType> &ArgTypes,
|
||||||
SmallVectorImpl<Expr*> &MsgExprs,
|
SmallVectorImpl<Expr*> &MsgExprs,
|
||||||
|
@ -3183,7 +3182,6 @@ void RewriteModernObjC::RewriteLineDirective(const Decl *D) {
|
||||||
/// starting with receiver.
|
/// starting with receiver.
|
||||||
/// Method - Method being rewritten.
|
/// Method - Method being rewritten.
|
||||||
Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
|
Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
|
||||||
QualType msgSendType,
|
|
||||||
QualType returnType,
|
QualType returnType,
|
||||||
SmallVectorImpl<QualType> &ArgTypes,
|
SmallVectorImpl<QualType> &ArgTypes,
|
||||||
SmallVectorImpl<Expr*> &MsgExprs,
|
SmallVectorImpl<Expr*> &MsgExprs,
|
||||||
|
@ -3199,6 +3197,7 @@ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFla
|
||||||
std::string name = "__Stret"; name += utostr(stretCount);
|
std::string name = "__Stret"; name += utostr(stretCount);
|
||||||
std::string str =
|
std::string str =
|
||||||
"extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
|
"extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
|
||||||
|
str += "namespace {\n";
|
||||||
str += "struct "; str += name;
|
str += "struct "; str += name;
|
||||||
str += " {\n\t";
|
str += " {\n\t";
|
||||||
str += name;
|
str += name;
|
||||||
|
@ -3217,9 +3216,27 @@ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFla
|
||||||
}
|
}
|
||||||
|
|
||||||
str += ") {\n";
|
str += ") {\n";
|
||||||
str += "\t if (receiver == 0)\n";
|
str += "\t unsigned size = sizeof(";
|
||||||
|
str += returnType.getAsString(Context->getPrintingPolicy()); str += ");\n";
|
||||||
|
|
||||||
|
str += "\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
|
||||||
|
|
||||||
|
str += "\t s = (("; str += castType.getAsString(Context->getPrintingPolicy());
|
||||||
|
str += ")(void *)objc_msgSend)(receiver, sel";
|
||||||
|
for (unsigned i = 2; i < ArgTypes.size(); i++) {
|
||||||
|
str += ", arg"; str += utostr(i);
|
||||||
|
}
|
||||||
|
// could be vararg.
|
||||||
|
for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
|
||||||
|
str += ", arg"; str += utostr(i);
|
||||||
|
}
|
||||||
|
str+= ");\n";
|
||||||
|
|
||||||
|
str += "\t else if (receiver == 0)\n";
|
||||||
str += "\t memset((void*)&s, 0, sizeof(s));\n";
|
str += "\t memset((void*)&s, 0, sizeof(s));\n";
|
||||||
str += "\t else\n";
|
str += "\t else\n";
|
||||||
|
|
||||||
|
|
||||||
str += "\t s = (("; str += castType.getAsString(Context->getPrintingPolicy());
|
str += "\t s = (("; str += castType.getAsString(Context->getPrintingPolicy());
|
||||||
str += ")(void *)objc_msgSend_stret)(receiver, sel";
|
str += ")(void *)objc_msgSend_stret)(receiver, sel";
|
||||||
for (unsigned i = 2; i < ArgTypes.size(); i++) {
|
for (unsigned i = 2; i < ArgTypes.size(); i++) {
|
||||||
|
@ -3229,12 +3246,13 @@ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFla
|
||||||
for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
|
for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
|
||||||
str += ", arg"; str += utostr(i);
|
str += ", arg"; str += utostr(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
str += ");\n";
|
str += ");\n";
|
||||||
|
|
||||||
|
|
||||||
str += "\t}\n";
|
str += "\t}\n";
|
||||||
str += "\t"; str += returnType.getAsString(Context->getPrintingPolicy());
|
str += "\t"; str += returnType.getAsString(Context->getPrintingPolicy());
|
||||||
str += " s;\n";
|
str += " s;\n";
|
||||||
str += "};\n\n";
|
str += "};\n};\n\n";
|
||||||
SourceLocation FunLocStart;
|
SourceLocation FunLocStart;
|
||||||
if (CurFunctionDef)
|
if (CurFunctionDef)
|
||||||
FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
|
FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
|
||||||
|
@ -3651,39 +3669,11 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
|
||||||
// expression which dictate which one to envoke depending on size of
|
// expression which dictate which one to envoke depending on size of
|
||||||
// method's return type.
|
// method's return type.
|
||||||
|
|
||||||
Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
|
Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
|
||||||
msgSendType, returnType,
|
returnType,
|
||||||
ArgTypes, MsgExprs,
|
ArgTypes, MsgExprs,
|
||||||
Exp->getMethodDecl());
|
Exp->getMethodDecl());
|
||||||
|
ReplacingStmt = STCE;
|
||||||
// Build sizeof(returnType)
|
|
||||||
UnaryExprOrTypeTraitExpr *sizeofExpr =
|
|
||||||
new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf,
|
|
||||||
Context->getTrivialTypeSourceInfo(returnType),
|
|
||||||
Context->getSizeType(), SourceLocation(),
|
|
||||||
SourceLocation());
|
|
||||||
// (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
|
|
||||||
// FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases.
|
|
||||||
// For X86 it is more complicated and some kind of target specific routine
|
|
||||||
// is needed to decide what to do.
|
|
||||||
unsigned IntSize =
|
|
||||||
static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
|
|
||||||
IntegerLiteral *limit = IntegerLiteral::Create(*Context,
|
|
||||||
llvm::APInt(IntSize, 8),
|
|
||||||
Context->IntTy,
|
|
||||||
SourceLocation());
|
|
||||||
BinaryOperator *lessThanExpr =
|
|
||||||
new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy,
|
|
||||||
VK_RValue, OK_Ordinary, SourceLocation(),
|
|
||||||
false);
|
|
||||||
// (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
|
|
||||||
ConditionalOperator *CondExpr =
|
|
||||||
new (Context) ConditionalOperator(lessThanExpr,
|
|
||||||
SourceLocation(), CE,
|
|
||||||
SourceLocation(), STCE,
|
|
||||||
returnType, VK_RValue, OK_Ordinary);
|
|
||||||
ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
|
|
||||||
CondExpr);
|
|
||||||
}
|
}
|
||||||
// delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
|
// delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
|
||||||
return ReplacingStmt;
|
return ReplacingStmt;
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
|
||||||
|
// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
|
||||||
|
// rdar://14932320
|
||||||
|
|
||||||
|
extern "C" void *sel_registerName(const char *);
|
||||||
|
typedef unsigned long size_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned long long x;
|
||||||
|
unsigned long long y;
|
||||||
|
} myPoint;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned long long x;
|
||||||
|
unsigned long long y;
|
||||||
|
} allPoint;
|
||||||
|
|
||||||
|
@interface Obj
|
||||||
|
+ (myPoint)foo;
|
||||||
|
+ (myPoint)foo : (int)Arg1 : (double)fArg;
|
||||||
|
+ (allPoint)fee;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation Obj
|
||||||
|
+ (allPoint)fee {
|
||||||
|
allPoint a;
|
||||||
|
a.x = a.y = 3;
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
+ (myPoint)foo {
|
||||||
|
myPoint r;
|
||||||
|
r.x = 1;
|
||||||
|
r.y = 2;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (myPoint)foo : (int)Arg1 : (double)fArg {
|
||||||
|
myPoint r;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
myPoint Ret_myPoint() {
|
||||||
|
return [Obj foo];
|
||||||
|
}
|
||||||
|
|
||||||
|
allPoint Ret_allPoint() {
|
||||||
|
return [Obj fee];
|
||||||
|
}
|
||||||
|
|
||||||
|
myPoint Ret_myPoint1(int i, double d) {
|
||||||
|
return [Obj foo:i:d];
|
||||||
|
}
|
||||||
|
|
||||||
|
myPoint Ret_myPoint2() {
|
||||||
|
return [Obj foo];
|
||||||
|
}
|
Loading…
Reference in New Issue