From: Steve Naroff Date: Tue, 23 Oct 2007 23:50:29 +0000 (+0000) Subject: Add some plumbing to rewrite message expressions (still under construction). X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ebf2b56bce1ea6b1b8133c1f0e2131503d229d2d;p=clang Add some plumbing to rewrite message expressions (still under construction). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43274 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp index 7cf1342591..42b5940e19 100644 --- a/Driver/RewriteTest.cpp +++ b/Driver/RewriteTest.cpp @@ -16,6 +16,7 @@ #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/IdentifierTable.h" using namespace clang; @@ -28,12 +29,17 @@ namespace { SourceLocation LastIncLoc; llvm::SmallVector ClassImplementation; llvm::SmallVector CategoryImplementation; + + FunctionDecl *MsgSendFunctionDecl; + FunctionDecl *GetClassFunctionDecl; + static const int OBJC_ABI_VERSION =7 ; public: void Initialize(ASTContext &context, unsigned mainFileID) { Context = &context; SM = &Context->SourceMgr; MainFileID = mainFileID; + MsgSendFunctionDecl = 0; Rewrite.setSourceMgr(Context->SourceMgr); } @@ -45,6 +51,7 @@ namespace { void RewriteFunctionBody(Stmt *S); void RewriteAtEncode(ObjCEncodeExpr *Exp); void RewriteForwardClassDecl(ObjcClassDecl *Dcl); + void RewriteMessageExpr(ObjCMessageExpr *Exp); void WriteObjcClassMetaData(ObjcImplementationDecl *IDecl); void WriteObjcMetaData(); @@ -65,6 +72,13 @@ void RewriteTest::HandleTopLevelDecl(Decl *D) { // If this is for a builtin, ignore it. if (Loc.isInvalid()) return; + // Look for built-in declarations that we need to refer during the rewrite. + if (FunctionDecl *FD = dyn_cast(D)) { + if (FD->getIdentifier() == &Context->Idents.get("objc_msgSend")) + MsgSendFunctionDecl = FD; + else if (FD->getIdentifier() == &Context->Idents.get("objc_getClass")) + GetClassFunctionDecl = FD; + } if (SM->getDecomposedFileLoc(Loc).first == MainFileID) return HandleDeclInMainFile(D); @@ -113,15 +127,19 @@ void RewriteTest::HandleDeclInMainFile(Decl *D) { void RewriteTest::RewriteFunctionBody(Stmt *S) { - // Handle specific things. - if (ObjCEncodeExpr *AtEncode = dyn_cast(S)) - return RewriteAtEncode(AtEncode); - // Otherwise, just rewrite all children. for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end(); CI != E; ++CI) if (*CI) RewriteFunctionBody(*CI); + + // Handle specific things. + if (ObjCEncodeExpr *AtEncode = dyn_cast(S)) + return RewriteAtEncode(AtEncode); + + if (ObjCMessageExpr *MessExpr = dyn_cast(S)) + return RewriteMessageExpr(MessExpr); + } void RewriteTest::RewriteAtEncode(ObjCEncodeExpr *Exp) { @@ -133,6 +151,33 @@ void RewriteTest::RewriteAtEncode(ObjCEncodeExpr *Exp) { delete Replacement; } + +void RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) { + assert(MsgSendFunctionDecl && "Can't find objc_msgSend() decl"); + //Exp->dumpPretty(); + //printf("\n"); + + // Synthesize a call to objc_msgSend(). + + // Get the type, we will need to reference it in a couple spots. + QualType msgSendType = MsgSendFunctionDecl->getType(); + + // Create a reference to the objc_msgSend() declaration. + DeclRefExpr *DRE = new DeclRefExpr(MsgSendFunctionDecl, msgSendType, + SourceLocation()); + + // Now, we cast the reference to a pointer to the objc_msgSend type. + QualType pToFunc = Context->getPointerType(msgSendType); + ImplicitCastExpr *ICE = new ImplicitCastExpr(pToFunc, DRE); + + const FunctionType *FT = msgSendType->getAsFunctionType(); + CallExpr *CE = new CallExpr(ICE, 0, 0, FT->getResultType(), + SourceLocation()); + Rewrite.ReplaceStmt(Exp, CE); + //Exp->dump(); + //CE->dump(); +} + void RewriteTest::RewriteForwardClassDecl(ObjcClassDecl *ClassDecl) { int numDecls = ClassDecl->getNumForwardDecls(); ObjcInterfaceDecl **ForwardDecls = ClassDecl->getForwardDecls(); diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index 267202c41d..f2f79456e8 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -243,7 +243,7 @@ 84AF36A00CB17A3B00C820A5 /* DeclObjC.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DeclObjC.h; path = clang/AST/DeclObjC.h; sourceTree = ""; }; 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = ""; }; 84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = ""; }; - 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = ""; }; DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = ""; }; DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = ""; }; @@ -750,7 +750,6 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */; - compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 08FB7794FE84155DC02AAC07 /* clang */; projectDirPath = "";