aboutsummaryrefslogtreecommitdiff
path: root/Driver/RewriteTest.cpp
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2007-10-30 23:14:51 +0000
committerSteve Naroff <snaroff@apple.com>2007-10-30 23:14:51 +0000
commit09b266eb2a014b7af4dc06126c47b7629030ce09 (patch)
tree5020e9fd9a0273b582009c32cdaa3930cbd75384 /Driver/RewriteTest.cpp
parent0d892d8bfddd4916cc4f3467e1184a623d0716da (diff)
Stop pre-defining objc_msgSend/objc_getClass in the preprocessor. Instead, I generate these declaration on the fly when rewriting a message expression.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43529 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Driver/RewriteTest.cpp')
-rw-r--r--Driver/RewriteTest.cpp57
1 files changed, 49 insertions, 8 deletions
diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp
index 109cd4d83c..8f3b754195 100644
--- a/Driver/RewriteTest.cpp
+++ b/Driver/RewriteTest.cpp
@@ -63,6 +63,7 @@ namespace {
void RewriteCategoryDecl(ObjcCategoryDecl *Dcl);
void RewriteProtocolDecl(ObjcProtocolDecl *Dcl);
void RewriteMethods(int nMethods, ObjcMethodDecl **Methods);
+ void RewriteFunctionDecl(FunctionDecl *FD);
// Expression Rewriting.
Stmt *RewriteFunctionBody(Stmt *S);
@@ -70,6 +71,9 @@ namespace {
Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
Expr **args, unsigned nargs);
+ void SynthMsgSendFunctionDecl();
+ void SynthGetClassFunctionDecl();
+
// Metadata emission.
void HandleObjcMetaDataEmission();
void RewriteObjcClassMetaData(ObjcImplementationDecl *IDecl,
@@ -117,12 +121,7 @@ void RewriteTest::HandleTopLevelDecl(Decl *D) {
// Look for built-in declarations that we need to refer during the rewrite.
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- if (strcmp(FD->getName(), "objc_msgSend") == 0)
- MsgSendFunctionDecl = FD;
- else if (strcmp(FD->getName(), "objc_getClass") == 0)
- GetClassFunctionDecl = FD;
- else if (strcmp(FD->getName(), "sel_getUid") == 0)
- SelGetUidFunctionDecl = FD;
+ RewriteFunctionDecl(FD);
} else if (ObjcInterfaceDecl *MD = dyn_cast<ObjcInterfaceDecl>(D)) {
RewriteInterfaceDecl(MD);
} else if (ObjcCategoryDecl *CD = dyn_cast<ObjcCategoryDecl>(D)) {
@@ -403,10 +402,52 @@ CallExpr *RewriteTest::SynthesizeCallToFunctionDecl(
return new CallExpr(ICE, args, nargs, FT->getResultType(), SourceLocation());
}
+void RewriteTest::RewriteFunctionDecl(FunctionDecl *FD) {
+ // declared in <objc/objc.h>
+ if (strcmp(FD->getName(), "sel_getUid") == 0)
+ SelGetUidFunctionDecl = FD;
+
+ // FIXME: Check if any types are isa<ObjcQualifiedInterfaceType> (yuck).
+}
+
+// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
+void RewriteTest::SynthMsgSendFunctionDecl() {
+ IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
+ llvm::SmallVector<QualType, 16> ArgTys;
+ QualType argT = Context->getObjcIdType();
+ assert(!argT.isNull() && "Can't find 'id' type");
+ ArgTys.push_back(argT);
+ argT = Context->getObjcSelType();
+ assert(!argT.isNull() && "Can't find 'SEL' type");
+ ArgTys.push_back(argT);
+ QualType msgSendType = Context->getFunctionType(Context->getObjcIdType(),
+ &ArgTys[0], ArgTys.size(),
+ true /*isVariadic*/);
+ MsgSendFunctionDecl = new FunctionDecl(SourceLocation(),
+ msgSendIdent, msgSendType,
+ FunctionDecl::Extern, false, 0);
+}
+
+// SynthGetClassFunctionDecl - id objc_getClass(const char *name);
+void RewriteTest::SynthGetClassFunctionDecl() {
+ IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
+ llvm::SmallVector<QualType, 16> ArgTys;
+ ArgTys.push_back(Context->getPointerType(
+ Context->CharTy.getQualifiedType(QualType::Const)));
+ QualType getClassType = Context->getFunctionType(Context->getObjcIdType(),
+ &ArgTys[0], ArgTys.size(),
+ false /*isVariadic*/);
+ GetClassFunctionDecl = new FunctionDecl(SourceLocation(),
+ getClassIdent, getClassType,
+ FunctionDecl::Extern, false, 0);
+}
+
Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) {
- assert(MsgSendFunctionDecl && "Can't find objc_msgSend() decl");
assert(SelGetUidFunctionDecl && "Can't find sel_getUid() decl");
- assert(GetClassFunctionDecl && "Can't find objc_getClass() decl");
+ if (!MsgSendFunctionDecl)
+ SynthMsgSendFunctionDecl();
+ if (!GetClassFunctionDecl)
+ SynthGetClassFunctionDecl();
// Synthesize a call to objc_msgSend().
llvm::SmallVector<Expr*, 8> MsgExprs;