aboutsummaryrefslogtreecommitdiff
path: root/Driver/RewriteTest.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2007-12-07 18:47:10 +0000
committerFariborz Jahanian <fjahanian@apple.com>2007-12-07 18:47:10 +0000
commit36ee2cb3247a662b6049f9cc097ba5cf9c0bb2b5 (patch)
treef75ba1dc03bc03517788b31f99cf34e37638ccb7 /Driver/RewriteTest.cpp
parent9bcb5fc1fd48c1f40c6a3b5a59130ebc313b4957 (diff)
Patch for rewriting of @protocol.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44681 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Driver/RewriteTest.cpp')
-rw-r--r--Driver/RewriteTest.cpp56
1 files changed, 52 insertions, 4 deletions
diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp
index 6b9c611c71..9c845a4473 100644
--- a/Driver/RewriteTest.cpp
+++ b/Driver/RewriteTest.cpp
@@ -50,6 +50,7 @@ namespace {
FunctionDecl *GetMetaClassFunctionDecl;
FunctionDecl *SelGetUidFunctionDecl;
FunctionDecl *CFStringFunctionDecl;
+ FunctionDecl *GetProtocolFunctionDecl;
// ObjC string constant support.
FileVarDecl *ConstantStringClassReference;
@@ -73,6 +74,7 @@ namespace {
GetMetaClassFunctionDecl = 0;
SelGetUidFunctionDecl = 0;
CFStringFunctionDecl = 0;
+ GetProtocolFunctionDecl = 0;
ConstantStringClassReference = 0;
NSStringRecord = 0;
CurMethodDecl = 0;
@@ -89,10 +91,15 @@ namespace {
// declaring objc_selector outside the parameter list removes a silly
// scope related warning...
const char *s = "struct objc_selector; struct objc_class;\n"
- "#ifndef OBJC_SUPER\n"
- "struct objc_super { struct objc_object *o; struct objc_object *superClass; };\n"
- "#define OBJC_SUPER\n"
- "#endif\n"
+ "#ifndef OBJC_SUPER\n"
+ "struct objc_super { struct objc_object *o; "
+ "struct objc_object *superClass; };\n"
+ "#define OBJC_SUPER\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"
"(struct objc_object *, struct objc_selector *, ...);\n"
"extern struct objc_object *objc_msgSendSuper"
@@ -113,6 +120,7 @@ namespace {
"extern struct objc_object *objc_exception_extract(void *);\n"
"extern int objc_exception_match"
"(struct objc_class *, struct objc_object *, ...);\n"
+ "extern Protocol *objc_getProtocol(const char *);\n"
"#include <objc/objc.h>\n";
Rewrite.InsertText(SourceLocation::getFileLoc(mainFileID, 0),
@@ -152,6 +160,7 @@ namespace {
Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
+ Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
Stmt *RewriteObjcTryStmt(ObjcAtTryStmt *S);
Stmt *RewriteObjcCatchStmt(ObjcAtCatchStmt *S);
Stmt *RewriteObjcFinallyStmt(ObjcAtFinallyStmt *S);
@@ -167,6 +176,7 @@ namespace {
void SynthGetMetaClassFunctionDecl();
void SynthCFStringFunctionDecl();
void SynthSelGetUidFunctionDecl();
+ void SynthGetProtocolFunctionDecl();
// Metadata emission.
void RewriteObjcClassMetaData(ObjcImplementationDecl *IDecl,
@@ -708,6 +718,9 @@ Stmt *RewriteTest::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
if (ObjcAtThrowStmt *StmtThrow = dyn_cast<ObjcAtThrowStmt>(S))
return RewriteObjcThrowStmt(StmtThrow);
+
+ if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
+ return RewriteObjCProtocolExpr(ProtocolExp);
#if 0
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
CastExpr *Replacement = new CastExpr(ICE->getType(), ICE->getSubExpr(), SourceLocation());
@@ -1036,6 +1049,20 @@ void RewriteTest::SynthSelGetUidFunctionDecl() {
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) {
// declared in <objc/objc.h>
if (strcmp(FD->getName(), "sel_registerName") == 0) {
@@ -1555,6 +1582,27 @@ Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) {
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
/// an objective-c class with ivars.
void RewriteTest::SynthesizeObjcInternalStruct(ObjcInterfaceDecl *CDecl,