From: Steve Naroff Date: Tue, 30 Oct 2007 23:14:51 +0000 (+0000) Subject: Stop pre-defining objc_msgSend/objc_getClass in the preprocessor. Instead, I generate... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=09b266eb2a014b7af4dc06126c47b7629030ce09;p=clang 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 --- 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(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(D)) { RewriteInterfaceDecl(MD); } else if (ObjcCategoryDecl *CD = dyn_cast(D)) { @@ -403,10 +402,52 @@ CallExpr *RewriteTest::SynthesizeCallToFunctionDecl( return new CallExpr(ICE, args, nargs, FT->getResultType(), SourceLocation()); } +void RewriteTest::RewriteFunctionDecl(FunctionDecl *FD) { + // declared in + if (strcmp(FD->getName(), "sel_getUid") == 0) + SelGetUidFunctionDecl = FD; + + // FIXME: Check if any types are isa (yuck). +} + +// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...); +void RewriteTest::SynthMsgSendFunctionDecl() { + IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend"); + llvm::SmallVector 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 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 MsgExprs; diff --git a/Lex/Preprocessor.cpp b/Lex/Preprocessor.cpp index 40abfe5cfc..784fb19e49 100644 --- a/Lex/Preprocessor.cpp +++ b/Lex/Preprocessor.cpp @@ -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 ). // We define the following header guard for source compatibility. It has // the effect of ignoring any explicit inclusion of :-) 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 - // . 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. diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index ac1c440885..ee3510785b 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -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); } diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index fe4cf8d85b..de41b4628d 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -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 = "";