forked from OSchip/llvm-project
Stop pre-defining objc_msgSend/objc_getClass in the preprocessor. Instead, I generate these declaration on the fly when rewriting a message expression.
llvm-svn: 43529
This commit is contained in:
parent
17833d7068
commit
5cdcd9b61c
|
@ -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;
|
||||
|
|
|
@ -369,15 +369,14 @@ static void InitializePredefinedMacros(Preprocessor &PP,
|
|||
DefineBuiltinMacro(Buf, "__OBJC__=1");
|
||||
if (PP.getLangOptions().ObjC2)
|
||||
DefineBuiltinMacro(Buf, "__OBJC2__=1");
|
||||
|
||||
if (PP.getLangOptions().ObjC1) {
|
||||
const char *ObjcType;
|
||||
// Predefine all the ObjC goodies (traditionally declared in <objc/objc.h>).
|
||||
// We define the following header guard for source compatibility. It has
|
||||
// the effect of ignoring any explicit inclusion of <objc/objc.h>:-)
|
||||
DefineBuiltinMacro(Buf, "_OBJC_OBJC_H_=1");
|
||||
DefineBuiltinMacro(Buf, "OBJC_EXPORT=extern");
|
||||
DefineBuiltinMacro(Buf, "OBJC_IMPORT=extern");
|
||||
const char *ObjcType;
|
||||
ObjcType = "typedef struct objc_class *Class;\n";
|
||||
Buf.insert(Buf.end(), ObjcType, ObjcType+strlen(ObjcType));
|
||||
ObjcType = "typedef struct objc_object { Class isa; } *id;\n";
|
||||
|
@ -396,19 +395,6 @@ static void InitializePredefinedMacros(Preprocessor &PP,
|
|||
Buf.insert(Buf.end(), ObjcType, ObjcType+strlen(ObjcType));
|
||||
ObjcType = "extern SEL sel_getUid(const char *str);\n";
|
||||
Buf.insert(Buf.end(), ObjcType, ObjcType+strlen(ObjcType));
|
||||
|
||||
// Predefine ObjC primitive functions, traditionally declared in
|
||||
// <objc/objc-runtime.h>. Unlike the declarations above, we don't protect
|
||||
// these with a header guard (since multiple identical function declarations
|
||||
// don't result in an error. FIXME: don't predefine these...
|
||||
ObjcType = "extern id objc_getClass(const char *name);\n";
|
||||
Buf.insert(Buf.end(), ObjcType, ObjcType+strlen(ObjcType));
|
||||
ObjcType = "extern id objc_getMetaClass(const char *name);\n";
|
||||
Buf.insert(Buf.end(), ObjcType, ObjcType+strlen(ObjcType));
|
||||
ObjcType = "extern id objc_msgSend(id self, SEL op, ...);\n";
|
||||
Buf.insert(Buf.end(), ObjcType, ObjcType+strlen(ObjcType));
|
||||
ObjcType = "extern id objc_msgSendSuper(struct objc_super *super, SEL op, ...);\n";
|
||||
Buf.insert(Buf.end(), ObjcType, ObjcType+strlen(ObjcType));
|
||||
}
|
||||
|
||||
// Add __builtin_va_list typedef.
|
||||
|
|
|
@ -2073,6 +2073,7 @@ Sema::ExprResult Sema::ActOnClassMessage(
|
|||
return true;
|
||||
}
|
||||
}
|
||||
GetObjcSelType(lbrac); // FIXME: a hack to install the sel type.
|
||||
return new ObjCMessageExpr(receiverName, Sel, returnType, lbrac, rbrac,
|
||||
ArgExprs);
|
||||
}
|
||||
|
@ -2130,5 +2131,6 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
|
|||
return true;
|
||||
}
|
||||
}
|
||||
GetObjcSelType(lbrac); // FIXME: a hack to install the sel type.
|
||||
return new ObjCMessageExpr(RExpr, Sel, returnType, lbrac, rbrac, ArgExprs);
|
||||
}
|
||||
|
|
|
@ -756,7 +756,6 @@
|
|||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
|
||||
compatibilityVersion = "Xcode 2.4";
|
||||
hasScannedForEncodings = 1;
|
||||
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
|
||||
projectDirPath = "";
|
||||
|
|
Loading…
Reference in New Issue