Index: include/clang/Analysis/PathSensitive/GRExprEngine.h
===================================================================
--- include/clang/Analysis/PathSensitive/GRExprEngine.h	(revision 47768)
+++ include/clang/Analysis/PathSensitive/GRExprEngine.h	(working copy)
@@ -420,4 +420,5 @@
   
   ValueState* MarkBranch(ValueState* St, Stmt* Terminator, bool branchTaken);
 };
-} // end clang namespace
\ No newline at end of file
+} // end clang namespace
+
Index: CodeGen/CGObjCRuntime.h
===================================================================
--- CodeGen/CGObjCRuntime.h	(revision 0)
+++ CodeGen/CGObjCRuntime.h	(revision 0)
@@ -0,0 +1,46 @@
+//===----- CGObjCRuntime.h - Emit LLVM Code from ASTs for a Module --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides an abstract class for Objective-C code generation.  Concrete
+// subclasses of this implement code generation for specific Objective-C
+// runtime libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_OBCJRUNTIME_H
+#define CLANG_CODEGEN_OBCJRUNTIME_H
+#include "clang/AST/AST.h"
+#include "clang/AST/Expr.h"
+namespace llvm {
+  class LLVMFoldingBuilder;
+  class Constant;
+  class Type;
+  class Value;
+  class Module;
+}
+
+namespace clang {
+namespace CodeGen {
+
+  // Implements runtime-specific code generation functions
+  class CGObjCRuntime {
+    public:
+      // Generate an Objective-C message send operation
+      virtual llvm::Value *generateMessageSend(llvm::LLVMFoldingBuilder &Builder,
+                                               const llvm::Type *ReturnTy,
+                                               llvm::Value *Receiver,
+                                               llvm::Constant *Selector,
+                                               llvm::Value** ArgV,
+                                               size_t ArgC) = 0;
+  };
+
+  CGObjCRuntime * ObjCDefaultRuntime(llvm::Module &M);
+}
+}
+#endif
Index: CodeGen/CGObjCGNU.cpp
===================================================================
--- CodeGen/CGObjCGNU.cpp	(revision 0)
+++ CodeGen/CGObjCGNU.cpp	(revision 0)
@@ -0,0 +1,98 @@
+//===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides Objective-C code generation targetting the GNU runtime.
+//
+//===----------------------------------------------------------------------===//
+#include "CGObjCRuntime.h"
+#include "llvm/Module.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/LLVMBuilder.h"
+#include <vector>
+
+using namespace clang::CodeGen;
+using namespace clang;
+using namespace llvm;
+
+class CGObjCGNU : public CGObjCRuntime {
+private:
+  Module &TheModule;
+public:
+  CGObjCGNU(Module &M) : TheModule(M) {};
+  virtual Value *generateMessageSend(llvm::LLVMFoldingBuilder &Builder,
+                                     const llvm::Type *ReturnTy,
+                                     llvm::Value *Receiver,
+                                     llvm::Constant *Selector,
+                                     llvm::Value** ArgV,
+                                     size_t ArgC);
+};
+
+// Generate code for a message send expression on the GNU runtime.
+// BIG FAT WARNING: Much of this code will need factoring out later.
+// FIXME: This currently only handles id returns.  Other return types 
+// need some explicit casting.
+Value *CGObjCGNU::generateMessageSend(llvm::LLVMFoldingBuilder &Builder,
+                                      const llvm::Type *ReturnTy,
+                                      llvm::Value *Receiver,
+                                      llvm::Constant *Selector,
+                                      llvm::Value** ArgV,
+                                      size_t ArgC) {
+  // Get the selector Type
+  const llvm::Type *PtrToInt8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+  std::vector<const llvm::Type*> Str2(2, PtrToInt8Ty);
+  const llvm::Type *SelStructTy = llvm::StructType::get(Str2);
+  const llvm::Type *SelTy = llvm::PointerType::getUnqual(SelStructTy);
+
+  // Look up the selector
+  //Function *SelFunction = TheModule.getFunction("sel_get_uid");
+  // If we haven't got the selector lookup function, look it up now.
+  // TODO: Factor this out and use it to implement @selector() too.
+  llvm::Constant *SelFunction = TheModule.getOrInsertFunction("sel_get_uid", 
+          SelTy, 
+          PtrToInt8Ty, 
+          NULL);
+  // FIXME: Selectors should be statically cached, not looked up on every call.
+  std::vector<Value*> SelArgs;
+  std::vector<Value*> IdxVector;
+  // TODO: Pull this out into the caller.
+  llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
+  llvm::Constant *Ops[] = {Idx0, Idx0};
+  llvm::Value *SelStr = llvm::ConstantExpr::getGetElementPtr(Selector, Ops, 2);
+  SelArgs.push_back(SelStr);
+  Value *cmd = Builder.CreateCall(SelFunction, SelArgs.begin(), SelArgs.end());
+
+  // Look up the method implementation
+  std::vector<const llvm::Type*> impArgTypes;
+  impArgTypes.push_back(Receiver->getType());
+  impArgTypes.push_back(SelTy);
+  // Avoid an explicit cast on the IMP by getting a version that has the right
+  // return type.
+  llvm::FunctionType *impType = llvm::FunctionType::get(ReturnTy,
+      impArgTypes,
+      true);
+  Constant *lookupFunction = TheModule.getOrInsertFunction("objc_msg_lookup",
+          llvm::PointerType::get(impType, 0),
+          Receiver->getType(),
+          SelTy,
+          0);
+  std::vector<Value*> lookupArgs;
+  lookupArgs.push_back(Receiver);
+  lookupArgs.push_back(cmd);
+  llvm::Value *imp = Builder.CreateCall(lookupFunction,
+      lookupArgs.begin(), 
+      lookupArgs.end());
+
+  // Call the method
+  lookupArgs.insert(lookupArgs.end(), ArgV, ArgV+ArgC);
+  return Builder.CreateCall(imp, lookupArgs.begin(), lookupArgs.end());
+}
+CGObjCRuntime * clang::CodeGen::ObjCDefaultRuntime(Module &M)
+{
+  return new CGObjCGNU(M);
+}
Index: CodeGen/CGExprConstant.cpp
===================================================================
--- CodeGen/CGExprConstant.cpp	(revision 47768)
+++ CodeGen/CGExprConstant.cpp	(working copy)
@@ -200,6 +200,9 @@
     
     // 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) {
Index: CodeGen/CodeGenModule.cpp
===================================================================
--- CodeGen/CodeGenModule.cpp	(revision 47768)
+++ CodeGen/CodeGenModule.cpp	(working copy)
@@ -31,8 +31,15 @@
                              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 = ObjCDefaultRuntime(M);
+}
 
+CodeGenModule::~CodeGenModule(void) {
+  delete Runtime;
+}
+
 /// WarnUnsupported - Print out a warning that codegen doesn't support the
 /// specified stmt yet.
 void CodeGenModule::WarnUnsupported(const Stmt *S, const char *Type) {
Index: CodeGen/CGExprScalar.cpp
===================================================================
--- CodeGen/CGExprScalar.cpp	(revision 47768)
+++ CodeGen/CGExprScalar.cpp	(working copy)
@@ -41,9 +41,14 @@
   : 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 @@
       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 @@
   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
Index: CodeGen/CodeGenModule.h
===================================================================
--- CodeGen/CodeGenModule.h	(revision 47768)
+++ CodeGen/CodeGenModule.h	(working copy)
@@ -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 @@
   const llvm::TargetData &TheTargetData;
   Diagnostic &Diags;
   CodeGenTypes Types;
+  CGObjCRuntime *Runtime;
 
   llvm::Function *MemCpyFn;
   llvm::Function *MemSetFn;
@@ -65,7 +67,9 @@
 public:
   CodeGenModule(ASTContext &C, const LangOptions &Features, llvm::Module &M, 
                 const llvm::TargetData &TD, Diagnostic &Diags);
+  ~CodeGenModule(void);
   
+  CGObjCRuntime *getObjCRuntime() { return Runtime; }
   ASTContext &getContext() const { return Context; }
   const LangOptions &getLangOptions() const { return Features; }
   llvm::Module &getModule() const { return TheModule; }
