Index: lib/CodeGen/CGStmt.cpp
===================================================================
--- lib/CodeGen/CGStmt.cpp	(revision 48734)
+++ lib/CodeGen/CGStmt.cpp	(working copy)
@@ -332,9 +332,6 @@
   // Emit the result value, even if unused, to evalute the side effects.
   const Expr *RV = S.getRetValue();
 
-  QualType FnRetTy = CurFuncDecl->getType().getCanonicalType();
-  FnRetTy = cast<FunctionType>(FnRetTy)->getResultType();
-  
   if (FnRetTy->isVoidType()) {
     // If the function returns void, emit ret void.
     Builder.CreateRetVoid();
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp	(revision 48734)
+++ lib/CodeGen/CodeGenFunction.cpp	(working copy)
@@ -55,13 +55,85 @@
          !T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
 }
 
+// Generate an Objective-C method.  An Objective-C method is a C function with
+// its pointer, name, and types registered in the class struture.  
+// FIXME: This method contains a lot of code copied and pasted from
+// GenerateCode.  This should be factored out.
+void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
+  llvm::SmallVector<const llvm::Type *, 16> ParamTypes;
+  for (unsigned i=0 ; i<OMD->param_size() ; i++) {
+    ParamTypes.push_back(ConvertType(OMD->getParamDecl(i)->getType()));
+  }
+  CurFn = CGM.getObjCRuntime()->MethodPreamble(ConvertType(OMD->getResultType()),
+      llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
+      ParamTypes.begin(),
+      OMD->param_size(),
+      OMD->isVariadic());
+  llvm::BasicBlock *EntryBB = new llvm::BasicBlock("entry", CurFn);
+  
+  // Create a marker to make it easy to insert allocas into the entryblock
+  // later.  Don't create this with the builder, because we don't want it
+  // folded.
+  llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
+  AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
+                                         EntryBB);
 
+  FnRetTy = OMD->getResultType(); ///.getCanonicalType();
+
+  Builder.SetInsertPoint(EntryBB);
+  
+  // Emit allocs for param decls.  Give the LLVM Argument nodes names.
+  llvm::Function::arg_iterator AI = CurFn->arg_begin();
+  
+  // Name the struct return argument.
+  // FIXME: Probably should be in the runtime, or it will trample the other
+  // hidden arguments.
+  if (hasAggregateLLVMType(OMD->getResultType())) {
+    AI->setName("agg.result");
+    ++AI;
+  }
+
+  // Skip the hidden arguments.
+  ++AI; ++AI;
+
+  for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) {
+    assert(AI != CurFn->arg_end() && "Argument mismatch!");
+    EmitParmDecl(*OMD->getParamDecl(i), AI);
+  }
+  
+  // Emit the function body.
+  EmitStmt(OMD->getBody());
+  
+  // Emit a return for code that falls off the end. If insert point
+  // is a dummy block with no predecessors then remove the block itself.
+  llvm::BasicBlock *BB = Builder.GetInsertBlock();
+  if (isDummyBlock(BB))
+    BB->eraseFromParent();
+  else {
+    if (CurFn->getReturnType() == llvm::Type::VoidTy)
+      Builder.CreateRetVoid();
+    else
+      Builder.CreateRet(llvm::UndefValue::get(CurFn->getReturnType()));
+  }
+  assert(BreakContinueStack.empty() &&
+         "mismatched push/pop in break/continue stack!");
+  
+  // Remove the AllocaInsertPt instruction, which is just a convenience for us.
+  AllocaInsertPt->eraseFromParent();
+  AllocaInsertPt = 0;
+  // Verify that the function is well formed.
+  assert(!verifyFunction(*CurFn));
+}
+
 void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
   LLVMIntTy = ConvertType(getContext().IntTy);
   LLVMPointerWidth = static_cast<unsigned>(
     getContext().getTypeSize(getContext().getPointerType(getContext().VoidTy)));
   
   CurFuncDecl = FD;
+  FnRetTy = CurFuncDecl->getType().getCanonicalType();
+  FnRetTy = cast<FunctionType>(FnRetTy)->getResultType();
+
   CurFn = cast<llvm::Function>(CGM.GetAddrOfFunctionDecl(FD, true));
   assert(CurFn->isDeclaration() && "Function already has body?");
   
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp	(revision 48734)
+++ lib/CodeGen/CodeGenModule.cpp	(working copy)
@@ -263,6 +272,12 @@
 }
 
 
+void CodeGenModule::EmitObjCMethod(const ObjCMethodDecl *OMD) {
+  // If this is not a prototype, emit the body.
+  if (OMD->getBody())
+    CodeGenFunction(*this).GenerateObjCMethod(OMD);
+}
+
 void CodeGenModule::EmitFunction(const FunctionDecl *FD) {
   // If this is not a prototype, emit the body.
   if (FD->getBody())
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h	(revision 48734)
+++ lib/CodeGen/CodeGenFunction.h	(working copy)
@@ -14,6 +14,7 @@
 #ifndef CLANG_CODEGEN_CODEGENFUNCTION_H
 #define CLANG_CODEGEN_CODEGENFUNCTION_H
 
+#include "clang/AST/Type.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/LLVMBuilder.h"
@@ -27,8 +28,8 @@
   class ASTContext;
   class Decl;
   class FunctionDecl;
+  class ObjCMethodDecl;
   class TargetInfo;
-  class QualType;
   class FunctionTypeProto;
   
   class Stmt;
@@ -66,6 +67,7 @@
   class ChooseExpr;
   class PreDefinedExpr;
   class ObjCStringLiteral;
+  class ObjCIvarRefExpr;
   class MemberExpr;
 
   class BlockVarDecl;
@@ -245,6 +247,7 @@
   llvm::LLVMFoldingBuilder Builder;
   
   const FunctionDecl *CurFuncDecl;
+  QualType FnRetTy;
   llvm::Function *CurFn;
 
   /// AllocaInsertPoint - This is an instruction in the entry block before which
@@ -286,6 +289,7 @@
   
   ASTContext &getContext() const;
 
+  void GenerateObjCMethod(const ObjCMethodDecl *OMD);
   void GenerateCode(const FunctionDecl *FD);
   
   const llvm::Type *ConvertType(QualType T);
@@ -422,7 +426,8 @@
 
   LValue EmitLValueForField(llvm::Value* Base, FieldDecl* Field,
                             bool isUnion);
-    
+      
+  LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E);
   //===--------------------------------------------------------------------===//
   //                         Scalar Expression Emission
   //===--------------------------------------------------------------------===//
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h	(revision 48734)
+++ lib/CodeGen/CodeGenModule.h	(working copy)
@@ -30,6 +30,7 @@
 namespace clang {
   class ASTContext;
   class FunctionDecl;
+  class ObjCMethodDecl;
   class Decl;
   class Expr;
   class Stmt;
@@ -100,6 +101,7 @@
   void AddGlobalCtor(llvm::Function * Ctor);
   void EmitGlobalCtors(void);
 
+  void EmitObjCMethod(const ObjCMethodDecl *OMD);
   void EmitFunction(const FunctionDecl *FD);
   void EmitGlobalVar(const FileVarDecl *D);
   void EmitGlobalVarDeclarator(const FileVarDecl *D);
