forked from OSchip/llvm-project
parent
bfd373a53e
commit
33c0e815f3
|
@ -50,6 +50,7 @@ namespace {
|
||||||
FunctionDecl *GetMetaClassFunctionDecl;
|
FunctionDecl *GetMetaClassFunctionDecl;
|
||||||
FunctionDecl *SelGetUidFunctionDecl;
|
FunctionDecl *SelGetUidFunctionDecl;
|
||||||
FunctionDecl *CFStringFunctionDecl;
|
FunctionDecl *CFStringFunctionDecl;
|
||||||
|
FunctionDecl *GetProtocolFunctionDecl;
|
||||||
|
|
||||||
// ObjC string constant support.
|
// ObjC string constant support.
|
||||||
FileVarDecl *ConstantStringClassReference;
|
FileVarDecl *ConstantStringClassReference;
|
||||||
|
@ -73,6 +74,7 @@ namespace {
|
||||||
GetMetaClassFunctionDecl = 0;
|
GetMetaClassFunctionDecl = 0;
|
||||||
SelGetUidFunctionDecl = 0;
|
SelGetUidFunctionDecl = 0;
|
||||||
CFStringFunctionDecl = 0;
|
CFStringFunctionDecl = 0;
|
||||||
|
GetProtocolFunctionDecl = 0;
|
||||||
ConstantStringClassReference = 0;
|
ConstantStringClassReference = 0;
|
||||||
NSStringRecord = 0;
|
NSStringRecord = 0;
|
||||||
CurMethodDecl = 0;
|
CurMethodDecl = 0;
|
||||||
|
@ -90,9 +92,14 @@ namespace {
|
||||||
// scope related warning...
|
// scope related warning...
|
||||||
const char *s = "struct objc_selector; struct objc_class;\n"
|
const char *s = "struct objc_selector; struct objc_class;\n"
|
||||||
"#ifndef OBJC_SUPER\n"
|
"#ifndef OBJC_SUPER\n"
|
||||||
"struct objc_super { struct objc_object *o; struct objc_object *superClass; };\n"
|
"struct objc_super { struct objc_object *o; "
|
||||||
|
"struct objc_object *superClass; };\n"
|
||||||
"#define OBJC_SUPER\n"
|
"#define OBJC_SUPER\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
"#ifndef _REWRITER_typedef_Protocol\n"
|
||||||
|
"typedef struct objc_object Protocol;\n"
|
||||||
|
"#define _REWRITER_typedef_Protocol\n"
|
||||||
|
"#endif\n"
|
||||||
"extern struct objc_object *objc_msgSend"
|
"extern struct objc_object *objc_msgSend"
|
||||||
"(struct objc_object *, struct objc_selector *, ...);\n"
|
"(struct objc_object *, struct objc_selector *, ...);\n"
|
||||||
"extern struct objc_object *objc_msgSendSuper"
|
"extern struct objc_object *objc_msgSendSuper"
|
||||||
|
@ -113,6 +120,7 @@ namespace {
|
||||||
"extern struct objc_object *objc_exception_extract(void *);\n"
|
"extern struct objc_object *objc_exception_extract(void *);\n"
|
||||||
"extern int objc_exception_match"
|
"extern int objc_exception_match"
|
||||||
"(struct objc_class *, struct objc_object *, ...);\n"
|
"(struct objc_class *, struct objc_object *, ...);\n"
|
||||||
|
"extern Protocol *objc_getProtocol(const char *);\n"
|
||||||
"#include <objc/objc.h>\n";
|
"#include <objc/objc.h>\n";
|
||||||
|
|
||||||
Rewrite.InsertText(SourceLocation::getFileLoc(mainFileID, 0),
|
Rewrite.InsertText(SourceLocation::getFileLoc(mainFileID, 0),
|
||||||
|
@ -152,6 +160,7 @@ namespace {
|
||||||
Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
|
Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
|
||||||
Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
|
Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
|
||||||
Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
|
Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
|
||||||
|
Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
|
||||||
Stmt *RewriteObjcTryStmt(ObjcAtTryStmt *S);
|
Stmt *RewriteObjcTryStmt(ObjcAtTryStmt *S);
|
||||||
Stmt *RewriteObjcCatchStmt(ObjcAtCatchStmt *S);
|
Stmt *RewriteObjcCatchStmt(ObjcAtCatchStmt *S);
|
||||||
Stmt *RewriteObjcFinallyStmt(ObjcAtFinallyStmt *S);
|
Stmt *RewriteObjcFinallyStmt(ObjcAtFinallyStmt *S);
|
||||||
|
@ -167,6 +176,7 @@ namespace {
|
||||||
void SynthGetMetaClassFunctionDecl();
|
void SynthGetMetaClassFunctionDecl();
|
||||||
void SynthCFStringFunctionDecl();
|
void SynthCFStringFunctionDecl();
|
||||||
void SynthSelGetUidFunctionDecl();
|
void SynthSelGetUidFunctionDecl();
|
||||||
|
void SynthGetProtocolFunctionDecl();
|
||||||
|
|
||||||
// Metadata emission.
|
// Metadata emission.
|
||||||
void RewriteObjcClassMetaData(ObjcImplementationDecl *IDecl,
|
void RewriteObjcClassMetaData(ObjcImplementationDecl *IDecl,
|
||||||
|
@ -708,6 +718,9 @@ Stmt *RewriteTest::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
|
||||||
|
|
||||||
if (ObjcAtThrowStmt *StmtThrow = dyn_cast<ObjcAtThrowStmt>(S))
|
if (ObjcAtThrowStmt *StmtThrow = dyn_cast<ObjcAtThrowStmt>(S))
|
||||||
return RewriteObjcThrowStmt(StmtThrow);
|
return RewriteObjcThrowStmt(StmtThrow);
|
||||||
|
|
||||||
|
if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
|
||||||
|
return RewriteObjCProtocolExpr(ProtocolExp);
|
||||||
#if 0
|
#if 0
|
||||||
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
|
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
|
||||||
CastExpr *Replacement = new CastExpr(ICE->getType(), ICE->getSubExpr(), SourceLocation());
|
CastExpr *Replacement = new CastExpr(ICE->getType(), ICE->getSubExpr(), SourceLocation());
|
||||||
|
@ -1036,6 +1049,20 @@ void RewriteTest::SynthSelGetUidFunctionDecl() {
|
||||||
FunctionDecl::Extern, false, 0);
|
FunctionDecl::Extern, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SynthGetProtocolFunctionDecl - Protocol objc_getProtocol(const char *proto);
|
||||||
|
void RewriteTest::SynthGetProtocolFunctionDecl() {
|
||||||
|
IdentifierInfo *SelGetProtoIdent = &Context->Idents.get("objc_getProtocol");
|
||||||
|
llvm::SmallVector<QualType, 16> ArgTys;
|
||||||
|
ArgTys.push_back(Context->getPointerType(
|
||||||
|
Context->CharTy.getQualifiedType(QualType::Const)));
|
||||||
|
QualType getFuncType = Context->getFunctionType(Context->getObjcProtoType(),
|
||||||
|
&ArgTys[0], ArgTys.size(),
|
||||||
|
false /*isVariadic*/);
|
||||||
|
GetProtocolFunctionDecl = new FunctionDecl(SourceLocation(),
|
||||||
|
SelGetProtoIdent, getFuncType,
|
||||||
|
FunctionDecl::Extern, false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void RewriteTest::RewriteFunctionDecl(FunctionDecl *FD) {
|
void RewriteTest::RewriteFunctionDecl(FunctionDecl *FD) {
|
||||||
// declared in <objc/objc.h>
|
// declared in <objc/objc.h>
|
||||||
if (strcmp(FD->getName(), "sel_registerName") == 0) {
|
if (strcmp(FD->getName(), "sel_registerName") == 0) {
|
||||||
|
@ -1555,6 +1582,27 @@ Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) {
|
||||||
return CE;
|
return CE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// RewriteObjCProtocolExpr - Rewrite a protocol expression into
|
||||||
|
/// call to objc_getProtocol("proto-name").
|
||||||
|
Stmt *RewriteTest::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
|
||||||
|
if (!GetProtocolFunctionDecl)
|
||||||
|
SynthGetProtocolFunctionDecl();
|
||||||
|
// Create a call to objc_getProtocol("ProtocolName").
|
||||||
|
llvm::SmallVector<Expr*, 8> ProtoExprs;
|
||||||
|
QualType argType = Context->getPointerType(Context->CharTy);
|
||||||
|
ProtoExprs.push_back(new StringLiteral(Exp->getProtocol()->getName(),
|
||||||
|
strlen(Exp->getProtocol()->getName()),
|
||||||
|
false, argType, SourceLocation(),
|
||||||
|
SourceLocation()));
|
||||||
|
CallExpr *ProtoExp = SynthesizeCallToFunctionDecl(GetProtocolFunctionDecl,
|
||||||
|
&ProtoExprs[0],
|
||||||
|
ProtoExprs.size());
|
||||||
|
Rewrite.ReplaceStmt(Exp, ProtoExp);
|
||||||
|
delete Exp;
|
||||||
|
return ProtoExp;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// SynthesizeObjcInternalStruct - Rewrite one internal struct corresponding to
|
/// SynthesizeObjcInternalStruct - Rewrite one internal struct corresponding to
|
||||||
/// an objective-c class with ivars.
|
/// an objective-c class with ivars.
|
||||||
void RewriteTest::SynthesizeObjcInternalStruct(ObjcInterfaceDecl *CDecl,
|
void RewriteTest::SynthesizeObjcInternalStruct(ObjcInterfaceDecl *CDecl,
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
// RUN: clang -rewrite-test %s
|
||||||
|
|
||||||
|
typedef struct MyWidget {
|
||||||
|
int a;
|
||||||
|
} MyWidget;
|
||||||
|
|
||||||
|
MyWidget gWidget = { 17 };
|
||||||
|
|
||||||
|
@protocol MyProto
|
||||||
|
- (MyWidget *)widget;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface Foo
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface Bar: Foo <MyProto>
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface Container
|
||||||
|
+ (MyWidget *)elementForView:(Foo *)view;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation Foo
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation Bar
|
||||||
|
- (MyWidget *)widget {
|
||||||
|
return &gWidget;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation Container
|
||||||
|
+ (MyWidget *)elementForView:(Foo *)view
|
||||||
|
{
|
||||||
|
MyWidget *widget = (void*)0;
|
||||||
|
if (@protocol(MyProto)) {
|
||||||
|
widget = [(id <MyProto>)view widget];
|
||||||
|
}
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
id view;
|
||||||
|
MyWidget *w = [Container elementForView: view];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue