diff options
author | Chris Lattner <sabre@nondot.org> | 2008-03-01 08:45:05 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-03-01 08:45:05 +0000 |
commit | 2b94fe35edf951a14ecd32b21f7ebcc2e3754c67 (patch) | |
tree | 03940ec1270cb024df1793b9dec75aa3dd938dce | |
parent | 72fc3b30d775a6b720dd0dd87aa853226f0625dd (diff) |
Add codegen support for ObjC message expressions with the GNU runtime.
Patch by David Chisnall!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47789 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | CodeGen/CGExprConstant.cpp | 3 | ||||
-rw-r--r-- | CodeGen/CGExprScalar.cpp | 49 | ||||
-rw-r--r-- | CodeGen/CodeGenModule.cpp | 9 | ||||
-rw-r--r-- | CodeGen/CodeGenModule.h | 4 | ||||
-rw-r--r-- | clang.xcodeproj/project.pbxproj | 6 |
5 files changed, 69 insertions, 2 deletions
diff --git a/CodeGen/CGExprConstant.cpp b/CodeGen/CGExprConstant.cpp index ec16b16a9d..30180c1774 100644 --- a/CodeGen/CGExprConstant.cpp +++ b/CodeGen/CGExprConstant.cpp @@ -200,6 +200,9 @@ public: // Make sure we have an array at this point assert(0 && "Unable to handle InitListExpr"); + // Get rid of control reaches end of void function warning. + // Not reached. + return 0; } llvm::Constant *VisitImplicitCastExpr(ImplicitCastExpr *ICExpr) { diff --git a/CodeGen/CGExprScalar.cpp b/CodeGen/CGExprScalar.cpp index 85831d5dd3..52b022b661 100644 --- a/CodeGen/CGExprScalar.cpp +++ b/CodeGen/CGExprScalar.cpp @@ -41,9 +41,14 @@ class VISIBILITY_HIDDEN ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, Value*> { CodeGenFunction &CGF; llvm::LLVMFoldingBuilder &Builder; + CGObjCRuntime *Runtime; + + public: - ScalarExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) { + ScalarExprEmitter(CodeGenFunction &cgf) : CGF(cgf), + Builder(CGF.Builder), + Runtime(CGF.CGM.getObjCRuntime()) { } @@ -120,6 +125,7 @@ public: return llvm::ConstantInt::get(EC->getInitVal()); return EmitLoadOfLValue(E); } + Value *VisitObjCMessageExpr(ObjCMessageExpr *E); Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E); Value *VisitMemberExpr(Expr *E) { return EmitLoadOfLValue(E); } Value *VisitOCUVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); } @@ -443,6 +449,47 @@ Value *ScalarExprEmitter::VisitExpr(Expr *E) { return llvm::UndefValue::get(CGF.ConvertType(E->getType())); } +Value *ScalarExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) { + // Only the lookup mechanism and first two arguments of the method + // implementation vary between runtimes. We can get the receiver and + // arguments in generic code. + + // Find the receiver + llvm::Value * Receiver = CGF.EmitScalarExpr(E->getReceiver()); + + // Process the arguments + unsigned int ArgC = E->getNumArgs(); + llvm::SmallVector<llvm::Value*, 16> Args; + for(unsigned i=0 ; i<ArgC ; i++) { + Expr *ArgExpr = E->getArg(i); + QualType ArgTy = ArgExpr->getType(); + if (!CGF.hasAggregateLLVMType(ArgTy)) { + // Scalar argument is passed by-value. + Args.push_back(CGF.EmitScalarExpr(ArgExpr)); + } else if (ArgTy->isComplexType()) { + // Make a temporary alloca to pass the argument. + llvm::Value *DestMem = CGF.CreateTempAlloca(ConvertType(ArgTy)); + CGF.EmitComplexExprIntoAddr(ArgExpr, DestMem, false); + Args.push_back(DestMem); + } else { + llvm::Value *DestMem = CGF.CreateTempAlloca(ConvertType(ArgTy)); + CGF.EmitAggExpr(ArgExpr, DestMem, false); + Args.push_back(DestMem); + } + } + + // Get the selector string + std::string SelStr = E->getSelector().getName(); + llvm::Constant *Selector = CGF.CGM.GetAddrOfConstantString(SelStr); + ConvertType(E->getType()); + return Runtime->generateMessageSend(Builder, + ConvertType(E->getType()), + Receiver, + Selector, + &Args[0], + Args.size()); +} + Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { // Emit subscript expressions in rvalue context's. For most cases, this just // loads the lvalue formed by the subscript expr. However, we have to be diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp index e3181337bf..5e63a80c94 100644 --- a/CodeGen/CodeGenModule.cpp +++ b/CodeGen/CodeGenModule.cpp @@ -31,7 +31,14 @@ CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO, llvm::Module &M, const llvm::TargetData &TD, Diagnostic &diags) : Context(C), Features(LO), TheModule(M), TheTargetData(TD), Diags(diags), - Types(C, M, TD), MemCpyFn(0), MemSetFn(0), CFConstantStringClassRef(0) {} + Types(C, M, TD), MemCpyFn(0), MemSetFn(0), CFConstantStringClassRef(0) { + //TODO: Make this selectable at runtime + Runtime = CreateObjCRuntime(M); +} + +CodeGenModule::~CodeGenModule() { + delete Runtime; +} /// WarnUnsupported - Print out a warning that codegen doesn't support the /// specified stmt yet. diff --git a/CodeGen/CodeGenModule.h b/CodeGen/CodeGenModule.h index 7863f7bebd..80ce3076d4 100644 --- a/CodeGen/CodeGenModule.h +++ b/CodeGen/CodeGenModule.h @@ -15,6 +15,7 @@ #define CLANG_CODEGEN_CODEGENMODULE_H #include "CodeGenTypes.h" +#include "CGObjCRuntime.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" @@ -52,6 +53,7 @@ class CodeGenModule { const llvm::TargetData &TheTargetData; Diagnostic &Diags; CodeGenTypes Types; + CGObjCRuntime *Runtime; llvm::Function *MemCpyFn; llvm::Function *MemSetFn; @@ -65,7 +67,9 @@ class CodeGenModule { public: CodeGenModule(ASTContext &C, const LangOptions &Features, llvm::Module &M, const llvm::TargetData &TD, Diagnostic &Diags); + ~CodeGenModule(); + CGObjCRuntime *getObjCRuntime() { return Runtime; } ASTContext &getContext() const { return Context; } const LangOptions &getLangOptions() const { return Features; } llvm::Module &getModule() const { return TheModule; } diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index dcbf2289f5..e9c86ca827 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -62,6 +62,7 @@ DE3461270AFE68BE00DBC861 /* MinimalAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */; }; DE34621D0AFEB19B00DBC861 /* StmtPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */; }; DE3464220B03040900DBC861 /* Type.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3464210B03040900DBC861 /* Type.h */; }; + DE38CD500D794D0100A273B6 /* CGObjCGNU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE38CD4F0D794D0100A273B6 /* CGObjCGNU.cpp */; }; DE3985790CB8ADC800223765 /* ASTConsumers.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3985780CB8ADC800223765 /* ASTConsumers.h */; }; DE39857B0CB8ADCB00223765 /* ASTConsumers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE39857A0CB8ADCB00223765 /* ASTConsumers.cpp */; }; DE3986F00CB8D4B300223765 /* IdentifierTable.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3986EF0CB8D4B300223765 /* IdentifierTable.h */; }; @@ -297,6 +298,8 @@ DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MinimalAction.cpp; path = Parse/MinimalAction.cpp; sourceTree = "<group>"; }; DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = StmtPrinter.cpp; path = AST/StmtPrinter.cpp; sourceTree = "<group>"; }; DE3464210B03040900DBC861 /* Type.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Type.h; path = clang/AST/Type.h; sourceTree = "<group>"; }; + DE38CD4E0D794CF900A273B6 /* CGObjCRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGObjCRuntime.h; path = CodeGen/CGObjCRuntime.h; sourceTree = "<group>"; }; + DE38CD4F0D794D0100A273B6 /* CGObjCGNU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGObjCGNU.cpp; path = CodeGen/CGObjCGNU.cpp; sourceTree = "<group>"; }; DE3985780CB8ADC800223765 /* ASTConsumers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ASTConsumers.h; path = Driver/ASTConsumers.h; sourceTree = "<group>"; }; DE39857A0CB8ADCB00223765 /* ASTConsumers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ASTConsumers.cpp; path = Driver/ASTConsumers.cpp; sourceTree = "<group>"; }; DE3986EF0CB8D4B300223765 /* IdentifierTable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IdentifierTable.h; sourceTree = "<group>"; }; @@ -586,6 +589,8 @@ 1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */, DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */, 1A7342470C7B57D500122F56 /* CGObjC.cpp */, + DE38CD4E0D794CF900A273B6 /* CGObjCRuntime.h */, + DE38CD4F0D794D0100A273B6 /* CGObjCGNU.cpp */, DE4772F90C10EAE5002239E8 /* CGStmt.cpp */, DE928B120C05659200231DA4 /* ModuleBuilder.cpp */, ); @@ -907,6 +912,7 @@ DE47999C0D2EBE1A00706D2D /* SemaExprObjC.cpp in Sources */, 03F50AC60D416EAA00B9CF60 /* Targets.cpp in Sources */, 1A376A2D0D4AED9B002A1C52 /* CGExprConstant.cpp in Sources */, + DE38CD500D794D0100A273B6 /* CGObjCGNU.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; |