diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
new file mode 100644
index 0000000..53034e9
--- /dev/null
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -0,0 +1,1032 @@
+//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// AST Consumer Implementations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/PathDiagnosticClients.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/CodeGen/ModuleBuilder.h"
+#include "llvm/Module.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+/// DeclPrinter - Utility class for printing top-level decls.
+
+namespace {
+  class DeclPrinter {
+  public:
+    llvm::raw_ostream& Out;
+    unsigned Indentation;
+
+    DeclPrinter(llvm::raw_ostream* out) : Out(out ? *out : llvm::errs()),
+                                          Indentation(0) {}
+    DeclPrinter() : Out(llvm::errs()), Indentation(0) {}
+    virtual ~DeclPrinter();
+    
+    void ChangeIndent(int I) {
+      Indentation += I;
+    }
+    
+    llvm::raw_ostream& Indent() {
+      for (unsigned i = 0; i < Indentation; ++i)
+        Out << "  ";
+      return Out;
+    }
+
+    void PrintDecl(Decl *D);
+    void Print(NamedDecl *ND);
+    void Print(NamespaceDecl *NS);
+    void PrintFunctionDeclStart(FunctionDecl *FD);    
+    void PrintTypeDefDecl(TypedefDecl *TD);    
+    void PrintLinkageSpec(LinkageSpecDecl *LS);
+    void PrintObjCMethodDecl(ObjCMethodDecl *OMD);    
+    void PrintObjCImplementationDecl(ObjCImplementationDecl *OID);
+    void PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID);
+    void PrintObjCProtocolDecl(ObjCProtocolDecl *PID);  
+    void PrintObjCCategoryImplDecl(ObjCCategoryImplDecl *PID);    
+    void PrintObjCCategoryDecl(ObjCCategoryDecl *PID);    
+    void PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID);
+    void PrintObjCPropertyDecl(ObjCPropertyDecl *PD);
+    void PrintObjCPropertyImplDecl(ObjCPropertyImplDecl *PID);
+
+    void PrintTemplateDecl(TemplateDecl *TD);
+  };
+} // end anonymous namespace
+
+DeclPrinter::~DeclPrinter() {
+  Out.flush();
+}
+
+void DeclPrinter:: PrintDecl(Decl *D) {
+  Indent();
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    PrintFunctionDeclStart(FD);
+
+    // FIXME: Pass a context here so we can use getBody()
+    if (FD->getBodyIfAvailable()) {
+      Out << ' ';
+      FD->getBodyIfAvailable()->printPretty(Out, 0, Indentation, true);
+      Out << '\n';
+    }
+  } else if (isa<ObjCMethodDecl>(D)) {
+    // Do nothing, methods definitions are printed in
+    // PrintObjCImplementationDecl.
+  } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+    PrintTypeDefDecl(TD);
+  } else if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(D)) {
+    PrintObjCInterfaceDecl(OID);
+  } else if (ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(D)) {
+    PrintObjCProtocolDecl(PID);
+  } else if (ObjCForwardProtocolDecl *OFPD = 
+             dyn_cast<ObjCForwardProtocolDecl>(D)) {
+    Out << "@protocol ";
+    for (ObjCForwardProtocolDecl::protocol_iterator I = OFPD->protocol_begin(), 
+                                                    E = OFPD->protocol_end();
+         I != E; ++I) {
+      if (I != OFPD->protocol_begin()) Out << ", ";
+      Out << (*I)->getNameAsString();
+    }
+    Out << ";\n";
+  } else if (ObjCImplementationDecl *OID = 
+             dyn_cast<ObjCImplementationDecl>(D)) {
+    PrintObjCImplementationDecl(OID);
+  } else if (ObjCCategoryImplDecl *OID = 
+             dyn_cast<ObjCCategoryImplDecl>(D)) {
+    PrintObjCCategoryImplDecl(OID);
+  } else if (ObjCCategoryDecl *OID = 
+             dyn_cast<ObjCCategoryDecl>(D)) {
+    PrintObjCCategoryDecl(OID);
+  } else if (ObjCCompatibleAliasDecl *OID = 
+             dyn_cast<ObjCCompatibleAliasDecl>(D)) {
+    PrintObjCCompatibleAliasDecl(OID);
+  } else if (ObjCClassDecl *OFCD = dyn_cast<ObjCClassDecl>(D)) {
+    Out << "@class ";
+    for (ObjCClassDecl::iterator I = OFCD->begin(), E = OFCD->end();
+         I != E; ++I) {
+      if (I != OFCD->begin()) Out << ", ";
+      Out << (*I)->getNameAsString();
+    }
+    Out << ";\n";
+  } else if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
+    Out << "enum " << ED->getNameAsString() << " {\n";
+    // FIXME: Shouldn't pass a NULL context
+    ASTContext *Context = 0;
+    for (EnumDecl::enumerator_iterator E = ED->enumerator_begin(*Context),
+                                    EEnd = ED->enumerator_end(*Context);
+         E != EEnd; ++E)
+      Out << "  " << (*E)->getNameAsString() << ",\n";
+    Out << "};\n";
+  } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
+    // print a free standing tag decl (e.g. "struct x;"). 
+    Out << TD->getKindName();
+    Out << " ";
+    if (const IdentifierInfo *II = TD->getIdentifier())
+      Out << II->getName();
+
+    if (TD->isDefinition()) {
+      Out << " {\n";
+      ChangeIndent(1);
+      // FIXME: Shouldn't pass a NULL context
+      ASTContext *Context = 0;
+      for (DeclContext::decl_iterator i = TD->decls_begin(*Context);
+           i != TD->decls_end(*Context);
+           ++i)
+        PrintDecl(*i);    
+      ChangeIndent(-1);
+      Indent();
+      Out << "}";
+    }
+    Out << ";\n";
+  } else if (TemplateDecl *TempD = dyn_cast<TemplateDecl>(D)) {
+    PrintTemplateDecl(TempD);
+  } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
+    PrintLinkageSpec(LSD);
+  } else if (FileScopeAsmDecl *AD = dyn_cast<FileScopeAsmDecl>(D)) {
+    Out << "asm(";
+    AD->getAsmString()->printPretty(Out);
+    Out << ")\n";
+  } else if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
+    Print(ND);
+  } else {
+    assert(0 && "Unknown decl type!");
+  }
+}
+
+void DeclPrinter::Print(NamedDecl *ND) {
+  switch (ND->getKind()) {
+  default:
+    // FIXME: Handle the rest of the NamedDecls.
+    Out << "### NamedDecl " << ND->getNameAsString() << "\n";
+    break;
+  case Decl::Field:
+  case Decl::Var: {
+    // Emit storage class for vardecls.
+    if (VarDecl *V = dyn_cast<VarDecl>(ND)) {
+      switch (V->getStorageClass()) {
+      default: assert(0 && "Unknown storage class!");
+      case VarDecl::None:          break;
+      case VarDecl::Auto:          Out << "auto "; break;
+      case VarDecl::Register:      Out << "register "; break;
+      case VarDecl::Extern:        Out << "extern "; break;
+      case VarDecl::Static:        Out << "static "; break; 
+      case VarDecl::PrivateExtern: Out << "__private_extern__ "; break; 
+      }
+    }
+    std::string Name = ND->getNameAsString();
+    // This forms: "int a".
+    dyn_cast<ValueDecl>(ND)->getType().getAsStringInternal(Name);
+    Out << Name;
+    if (VarDecl *Var = dyn_cast<VarDecl>(ND)) {
+      if (Var->getInit()) {
+        Out << " = ";
+        Var->getInit()->printPretty(Out);
+      }
+    }
+    Out << ";\n";
+    break;
+  }
+  case Decl::Namespace:
+    Print(dyn_cast<NamespaceDecl>(ND));
+    break;
+  }
+}
+
+void DeclPrinter::Print(NamespaceDecl *NS) {
+  Out << "namespace " << NS->getNameAsString() << " {\n";
+  ChangeIndent(1);
+  // FIXME: Shouldn't pass a NULL context
+  ASTContext *Context = 0;
+  for (DeclContext::decl_iterator i = NS->decls_begin(*Context);
+       i != NS->decls_end(*Context);
+       ++i)
+    PrintDecl(*i);    
+  ChangeIndent(-1);
+  Indent();
+  Out << "}\n";
+}
+
+void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) {
+  // FIXME: pass a context so that we can use getBody.
+  bool HasBody = FD->getBodyIfAvailable();
+  
+  Out << '\n';
+
+  Indent();
+  switch (FD->getStorageClass()) {
+  default: assert(0 && "Unknown storage class");
+  case FunctionDecl::None: break;
+  case FunctionDecl::Extern: Out << "extern "; break;
+  case FunctionDecl::Static: Out << "static "; break;
+  case FunctionDecl::PrivateExtern: Out << "__private_extern__ "; break;
+  }
+  
+  if (FD->isInline())
+    Out << "inline ";
+  
+  std::string Proto = FD->getNameAsString();
+  const FunctionType *AFT = FD->getType()->getAsFunctionType();
+
+  if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT)) {
+    Proto += "(";
+    for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
+      if (i) Proto += ", ";
+      std::string ParamStr;
+      if (HasBody) ParamStr = FD->getParamDecl(i)->getNameAsString();
+      
+      FT->getArgType(i).getAsStringInternal(ParamStr);
+      Proto += ParamStr;
+    }
+    
+    if (FT->isVariadic()) {
+      if (FD->getNumParams()) Proto += ", ";
+      Proto += "...";
+    }
+    Proto += ")";
+  } else {
+    assert(isa<FunctionNoProtoType>(AFT));
+    Proto += "()";
+  }
+
+  AFT->getResultType().getAsStringInternal(Proto);
+  Out << Proto;
+  
+  if (!FD->getBodyIfAvailable())
+    Out << ";\n";
+  // Doesn't print the body.
+}
+
+void DeclPrinter::PrintTypeDefDecl(TypedefDecl *TD) {
+  std::string S = TD->getNameAsString();
+  TD->getUnderlyingType().getAsStringInternal(S);
+  Out << "typedef " << S << ";\n";
+}
+
+void DeclPrinter::PrintLinkageSpec(LinkageSpecDecl *LS) {
+  const char *l;
+  if (LS->getLanguage() == LinkageSpecDecl::lang_c)
+    l = "C";
+  else {
+    assert(LS->getLanguage() == LinkageSpecDecl::lang_cxx &&
+           "unknown language in linkage specification");
+    l = "C++";
+  }
+
+  Out << "extern \"" << l << "\" ";
+  if (LS->hasBraces()) {
+    Out << "{\n";
+    ChangeIndent(1);
+  }
+
+  // FIXME: Should not use a NULL DeclContext!
+  ASTContext *Context = 0;
+  for (LinkageSpecDecl::decl_iterator D = LS->decls_begin(*Context), 
+                                   DEnd = LS->decls_end(*Context);
+       D != DEnd; ++D)
+    PrintDecl(*D);
+
+  if (LS->hasBraces()) {
+    ChangeIndent(-1);
+    Indent() << "}";
+  }
+  Out << "\n";
+}
+
+void DeclPrinter::PrintObjCMethodDecl(ObjCMethodDecl *OMD) {
+  if (OMD->isInstanceMethod())
+    Out << "\n- ";
+  else 
+    Out << "\n+ ";
+  if (!OMD->getResultType().isNull())
+    Out << '(' << OMD->getResultType().getAsString() << ")";
+  
+  std::string name = OMD->getSelector().getAsString();
+  std::string::size_type pos, lastPos = 0;
+  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
+       E = OMD->param_end(); PI != E; ++PI) {
+    // FIXME: selector is missing here!    
+    pos = name.find_first_of(":", lastPos);
+    Out << " " << name.substr(lastPos, pos - lastPos);
+    Out << ":(" << (*PI)->getType().getAsString() << ")"
+        << (*PI)->getNameAsString(); 
+    lastPos = pos + 1;
+  }
+    
+  if (OMD->param_begin() == OMD->param_end())
+    Out << " " << name;
+    
+  if (OMD->isVariadic())
+      Out << ", ...";
+  
+  Out << ";";
+}
+
+void DeclPrinter::PrintObjCImplementationDecl(ObjCImplementationDecl *OID) {
+  std::string I = OID->getNameAsString();
+  ObjCInterfaceDecl *SID = OID->getSuperClass();
+
+  if (SID)
+    Out << "@implementation " << I << " : " << SID->getNameAsString();
+  else
+    Out << "@implementation " << I;
+  
+  // FIXME: Don't use a NULL context
+  ASTContext *Context = 0;
+  for (ObjCImplementationDecl::instmeth_iterator 
+         I = OID->instmeth_begin(*Context),
+         E = OID->instmeth_end(*Context); 
+       I != E; ++I) {
+    ObjCMethodDecl *OMD = *I;
+    PrintObjCMethodDecl(OMD);
+    if (OMD->getBody()) {
+      Out << ' ';
+      OMD->getBody()->printPretty(Out);
+      Out << '\n';
+    }
+  }
+  
+  for (ObjCImplementationDecl::classmeth_iterator 
+         I = OID->classmeth_begin(*Context),
+       E = OID->classmeth_end(*Context);
+       I != E; ++I) {
+    ObjCMethodDecl *OMD = *I;
+    PrintObjCMethodDecl(OMD);
+    if (OMD->getBody()) {
+      Out << ' ';
+      OMD->getBody()->printPretty(Out);
+      Out << '\n';
+    }
+  }
+  
+  for (ObjCImplementationDecl::propimpl_iterator 
+         I = OID->propimpl_begin(*Context),
+         E = OID->propimpl_end(*Context); I != E; ++I)
+    PrintObjCPropertyImplDecl(*I);
+  
+  Out << "@end\n";
+}
+
+
+void DeclPrinter::PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
+  std::string I = OID->getNameAsString();
+  ObjCInterfaceDecl *SID = OID->getSuperClass();
+
+  if (SID)
+    Out << "@interface " << I << " : " << SID->getNameAsString();
+  else
+    Out << "@interface " << I;
+  
+  // Protocols?
+  const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
+  if (!Protocols.empty()) {
+    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+         E = Protocols.end(); I != E; ++I)
+      Out << (I == Protocols.begin() ? '<' : ',') << (*I)->getNameAsString();
+  }
+  
+  if (!Protocols.empty())
+    Out << ">";
+  Out << '\n';
+  
+  if (OID->ivar_size() > 0) {
+    Out << '{';
+    for (ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(),
+         E = OID->ivar_end(); I != E; ++I) {
+      Out << '\t' << (*I)->getType().getAsString()
+          << ' '  << (*I)->getNameAsString() << ";\n";      
+    }
+    Out << "}\n";
+  }
+  
+  // FIXME: Should not use a NULL DeclContext!
+  ASTContext *Context = 0;
+  for (ObjCInterfaceDecl::prop_iterator I = OID->prop_begin(*Context),
+       E = OID->prop_end(*Context); I != E; ++I)
+    PrintObjCPropertyDecl(*I);
+  bool eol_needed = false;
+  for (ObjCInterfaceDecl::classmeth_iterator I = OID->classmeth_begin(*Context),
+       E = OID->classmeth_end(*Context); I != E; ++I)
+    eol_needed = true, PrintObjCMethodDecl(*I);
+  
+  for (ObjCInterfaceDecl::instmeth_iterator I = OID->instmeth_begin(*Context),
+       E = OID->instmeth_end(*Context); I != E; ++I)
+    eol_needed = true, PrintObjCMethodDecl(*I);
+  
+  Out << (eol_needed ? "\n@end\n" : "@end\n");
+  // FIXME: implement the rest...
+}
+
+void DeclPrinter::PrintObjCProtocolDecl(ObjCProtocolDecl *PID) {
+  Out << "@protocol " << PID->getNameAsString() << '\n';
+  
+  // FIXME: Should not use a NULL DeclContext!
+  ASTContext *Context = 0;
+  for (ObjCProtocolDecl::prop_iterator I = PID->prop_begin(*Context),
+       E = PID->prop_end(*Context); I != E; ++I)
+    PrintObjCPropertyDecl(*I);
+  Out << "@end\n";
+  // FIXME: implement the rest...
+}
+
+void DeclPrinter::PrintObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
+  Out << "@implementation "
+      << PID->getClassInterface()->getNameAsString()
+      << '(' << PID->getNameAsString() << ");\n";  
+
+  // FIXME: Don't use a NULL context here
+  ASTContext *Context = 0;
+  for (ObjCCategoryImplDecl::propimpl_iterator 
+         I = PID->propimpl_begin(*Context),
+       E = PID->propimpl_end(*Context); I != E; ++I)
+    PrintObjCPropertyImplDecl(*I);
+  Out << "@end\n";
+  // FIXME: implement the rest...
+}
+
+void DeclPrinter::PrintObjCCategoryDecl(ObjCCategoryDecl *PID) {
+  // FIXME: Should not use a NULL DeclContext!
+  ASTContext *Context = 0;
+  Out << "@interface " 
+      << PID->getClassInterface()->getNameAsString()
+      << '(' << PID->getNameAsString() << ");\n";
+  // Output property declarations.
+  for (ObjCCategoryDecl::prop_iterator I = PID->prop_begin(*Context),
+       E = PID->prop_end(*Context); I != E; ++I)
+    PrintObjCPropertyDecl(*I);
+  Out << "@end\n";
+  
+  // FIXME: implement the rest...
+}
+
+void DeclPrinter::PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
+  Out << "@compatibility_alias " << AID->getNameAsString() 
+      << ' ' << AID->getClassInterface()->getNameAsString() << ";\n";  
+}
+
+/// PrintObjCPropertyDecl - print a property declaration.
+///
+void DeclPrinter::PrintObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
+  if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Required)
+    Out << "@required\n";
+  else if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Optional)
+    Out << "@optional\n";
+  
+  Out << "@property";
+  if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) {
+    bool first = true;
+    Out << " (";
+    if (PDecl->getPropertyAttributes() & 
+        ObjCPropertyDecl::OBJC_PR_readonly) {
+      Out << (first ? ' ' : ',') << "readonly";
+      first = false;
+  }
+      
+  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
+    Out << (first ? ' ' : ',') << "getter = "
+        << PDecl->getGetterName().getAsString();
+    first = false;
+  }
+  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
+    Out << (first ? ' ' : ',') << "setter = "
+        << PDecl->getSetterName().getAsString();
+    first = false;
+  }
+      
+  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) {
+    Out << (first ? ' ' : ',') << "assign";
+    first = false;
+  }
+      
+  if (PDecl->getPropertyAttributes() &
+      ObjCPropertyDecl::OBJC_PR_readwrite) {
+    Out << (first ? ' ' : ',') << "readwrite";
+    first = false;
+  }
+      
+  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) {
+    Out << (first ? ' ' : ',') << "retain";
+    first = false;
+  }
+      
+  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) {
+    Out << (first ? ' ' : ',') << "copy";
+    first = false;
+  }
+      
+  if (PDecl->getPropertyAttributes() & 
+      ObjCPropertyDecl::OBJC_PR_nonatomic) {
+    Out << (first ? ' ' : ',') << "nonatomic";
+    first = false;
+  }
+  Out << " )";
+  }
+  Out << ' ' << PDecl->getType().getAsString()
+  << ' ' << PDecl->getNameAsString();
+    
+  Out << ";\n";
+}
+
+/// PrintObjCPropertyImplDecl - Print an objective-c property implementation
+/// declaration syntax.
+///
+void DeclPrinter::PrintObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
+  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
+    Out << "\n@synthesize ";
+  else
+    Out << "\n@dynamic ";
+  Out << PID->getPropertyDecl()->getNameAsString();
+  if (PID->getPropertyIvarDecl())
+    Out << "=" << PID->getPropertyIvarDecl()->getNameAsString();
+  Out << ";\n";
+}
+
+/// PrintTemplateParams - Print a template parameter list and recursively print
+/// it's underlying top-level definition.
+void DeclPrinter::PrintTemplateDecl(TemplateDecl *TD) {
+  // TODO: Write template parameters.
+  Out << "template <...> ";
+  PrintDecl(TD->getTemplatedDecl());
+}
+
+
+
+//===----------------------------------------------------------------------===//
+/// ASTPrinter - Pretty-printer of ASTs
+
+namespace {
+  class ASTPrinter : public ASTConsumer, public DeclPrinter {
+  public:
+    ASTPrinter(llvm::raw_ostream* o = NULL) : DeclPrinter(o) {}
+    
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+        PrintDecl(*I);
+    }
+  };
+} // end anonymous namespace
+
+ASTConsumer *clang::CreateASTPrinter(llvm::raw_ostream* out) {
+  return new ASTPrinter(out);
+}
+
+//===----------------------------------------------------------------------===//
+/// ASTDumper - Low-level dumper of ASTs
+
+namespace {
+  class ASTDumper : public ASTConsumer, public DeclPrinter {
+    ASTContext *Ctx;
+    bool FullDump;
+
+  public:
+    explicit ASTDumper(bool FullDump) : DeclPrinter(), FullDump(FullDump) {}
+    
+    void Initialize(ASTContext &Context) {
+      Ctx = &Context;
+    }
+
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      if (FullDump)
+        return;
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+        HandleTopLevelSingleDecl(*I);
+    }
+    void HandleTopLevelSingleDecl(Decl *D);
+
+    virtual void HandleTranslationUnit(ASTContext &Ctx) {
+      if (!FullDump)
+        return;
+
+      for (DeclContext::decl_iterator 
+             D = Ctx.getTranslationUnitDecl()->decls_begin(Ctx),
+             DEnd = Ctx.getTranslationUnitDecl()->decls_end(Ctx);
+           D != DEnd; 
+           ++D)
+        HandleTopLevelSingleDecl(*D);
+    }
+  };
+} // end anonymous namespace
+
+void ASTDumper::HandleTopLevelSingleDecl(Decl *D) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    PrintFunctionDeclStart(FD);
+    
+    if (Stmt *Body = FD->getBody(*Ctx)) {
+      Out << '\n';
+      // FIXME: convert dumper to use raw_ostream.
+      Body->dumpAll(Ctx->getSourceManager());
+      Out << '\n';
+    }
+  } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+    PrintTypeDefDecl(TD);
+  } else if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(D)) {
+    Out << "Read objc interface '" << OID->getNameAsString() << "'\n";
+  } else if (ObjCProtocolDecl *OPD = dyn_cast<ObjCProtocolDecl>(D)) {
+    Out << "Read objc protocol '" << OPD->getNameAsString() << "'\n";
+  } else if (ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(D)) {
+    Out << "Read objc category '" << OCD->getNameAsString() << "'\n";
+  } else if (isa<ObjCForwardProtocolDecl>(D)) {
+    Out << "Read objc fwd protocol decl\n";
+  } else if (isa<ObjCClassDecl>(D)) {
+    Out << "Read objc fwd class decl\n";
+  } else if (isa<FileScopeAsmDecl>(D)) {
+    Out << "Read file scope asm decl\n";
+  } else if (ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D)) {
+    Out << "Read objc method decl: '" << MD->getSelector().getAsString()
+    << "'\n";
+    if (Stmt *S = MD->getBody()) {
+      // FIXME: convert dumper to use raw_ostream.
+      S->dumpAll(Ctx->getSourceManager());
+      Out << '\n';
+    }
+  } else if (isa<ObjCImplementationDecl>(D)) {
+    Out << "Read objc implementation decl\n";
+  } else if (isa<ObjCCategoryImplDecl>(D)) {
+    Out << "Read objc category implementation decl\n";
+  } else if (isa<LinkageSpecDecl>(D)) {
+    Out << "Read linkage spec decl\n";
+  } else if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
+    Out << "Read top-level variable decl: '" << ND->getNameAsString()
+    << "'\n";
+  } else {
+    assert(0 && "Unknown decl type!");
+  }
+}
+
+ASTConsumer *clang::CreateASTDumper(bool FullDump) { 
+  return new ASTDumper(FullDump); 
+}
+
+//===----------------------------------------------------------------------===//
+/// ASTViewer - AST Visualization
+
+namespace {
+  class ASTViewer : public ASTConsumer {
+    SourceManager *SM;
+  public:
+    void Initialize(ASTContext &Context) {
+      SM = &Context.getSourceManager();
+    }
+
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+        HandleTopLevelSingleDecl(*I);
+    }
+    
+    void HandleTopLevelSingleDecl(Decl *D);
+  };
+}
+
+void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    DeclPrinter().PrintFunctionDeclStart(FD);
+    
+    if (FD->getBodyIfAvailable()) {
+      llvm::cerr << '\n';
+      FD->getBodyIfAvailable()->viewAST();
+      llvm::cerr << '\n';
+    }
+    return;
+  }
+  
+  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    DeclPrinter().PrintObjCMethodDecl(MD);
+    
+    if (MD->getBody()) {
+      llvm::cerr << '\n';
+      MD->getBody()->viewAST();
+      llvm::cerr << '\n';
+    }
+  }
+}
+
+
+ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
+
+//===----------------------------------------------------------------------===//
+/// DeclContextPrinter - Decl and DeclContext Visualization
+
+namespace {
+
+class DeclContextPrinter : public ASTConsumer {
+  llvm::raw_ostream& Out;
+public:
+  DeclContextPrinter() : Out(llvm::errs()) {}
+
+  void HandleTranslationUnit(ASTContext &C) {
+    PrintDeclContext(C.getTranslationUnitDecl(), 4);
+  }
+
+  void PrintDeclContext(const DeclContext* DC, unsigned Indentation);
+};
+}  // end anonymous namespace
+
+void DeclContextPrinter::PrintDeclContext(const DeclContext* DC, 
+                                          unsigned Indentation) {
+  // Print DeclContext name.
+  switch (DC->getDeclKind()) {
+  case Decl::TranslationUnit:
+    Out << "[translation unit] " << DC;
+    break;
+  case Decl::Namespace: {
+    Out << "[namespace] ";
+    const NamespaceDecl* ND = cast<NamespaceDecl>(DC);
+    Out << ND->getNameAsString();
+    break;
+  }
+  case Decl::Enum: {
+    const EnumDecl* ED = cast<EnumDecl>(DC);
+    if (ED->isDefinition())
+      Out << "[enum] ";
+    else
+      Out << "<enum> ";
+    Out << ED->getNameAsString();
+    break;
+  }
+  case Decl::Record: {
+    const RecordDecl* RD = cast<RecordDecl>(DC);
+    if (RD->isDefinition())
+      Out << "[struct] ";
+    else
+      Out << "<struct> ";
+    Out << RD->getNameAsString();
+    break;
+  }
+  case Decl::CXXRecord: {
+    const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC);
+    if (RD->isDefinition())
+      Out << "[class] ";
+    else
+      Out << "<class> ";
+    Out << RD->getNameAsString() << " " << DC;
+    break;
+  }
+  case Decl::ObjCMethod:
+    Out << "[objc method]";
+    break;
+  case Decl::ObjCInterface:
+    Out << "[objc interface]";
+    break;
+  case Decl::ObjCCategory:
+    Out << "[objc category]";
+    break;
+  case Decl::ObjCProtocol:
+    Out << "[objc protocol]";
+    break;
+  case Decl::ObjCImplementation:
+    Out << "[objc implementation]";
+    break;
+  case Decl::ObjCCategoryImpl:
+    Out << "[objc categoryimpl]";
+    break;
+  case Decl::LinkageSpec:
+    Out << "[linkage spec]";
+    break;
+  case Decl::Block:
+    Out << "[block]";
+    break;
+  case Decl::Function: {
+    const FunctionDecl* FD = cast<FunctionDecl>(DC);
+    if (FD->isThisDeclarationADefinition())
+      Out << "[function] ";
+    else
+      Out << "<function> ";
+    Out << FD->getNameAsString();
+    // Print the parameters.
+    Out << "(";
+    bool PrintComma = false;
+    for (FunctionDecl::param_const_iterator I = FD->param_begin(), 
+           E = FD->param_end(); I != E; ++I) {
+      if (PrintComma)
+        Out << ", ";
+      else
+        PrintComma = true;
+      Out << (*I)->getNameAsString();
+    }
+    Out << ")";
+    break;
+  }
+  case Decl::CXXMethod: {
+    const CXXMethodDecl* D = cast<CXXMethodDecl>(DC);
+    if (D->isOutOfLineDefinition())
+      Out << "[c++ method] ";
+    else if (D->isImplicit())
+      Out << "(c++ method) ";
+    else
+      Out << "<c++ method> ";
+    Out << D->getNameAsString();
+    // Print the parameters.
+    Out << "(";
+    bool PrintComma = false;
+    for (FunctionDecl::param_const_iterator I = D->param_begin(), 
+           E = D->param_end(); I != E; ++I) {
+      if (PrintComma)
+        Out << ", ";
+      else
+        PrintComma = true;
+      Out << (*I)->getNameAsString();
+    }
+    Out << ")";
+
+    // Check the semantic DeclContext.
+    const DeclContext* SemaDC = D->getDeclContext();
+    const DeclContext* LexicalDC = D->getLexicalDeclContext();
+    if (SemaDC != LexicalDC)
+      Out << " [[" << SemaDC << "]]";
+
+    break;
+  }
+  case Decl::CXXConstructor: {
+    const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC);
+    if (D->isOutOfLineDefinition())
+      Out << "[c++ ctor] ";
+    else if (D->isImplicit())
+      Out << "(c++ ctor) ";
+    else
+      Out << "<c++ ctor> ";
+    Out << D->getNameAsString();
+    // Print the parameters.
+    Out << "(";
+    bool PrintComma = false;
+    for (FunctionDecl::param_const_iterator I = D->param_begin(), 
+           E = D->param_end(); I != E; ++I) {
+      if (PrintComma)
+        Out << ", ";
+      else
+        PrintComma = true;
+      Out << (*I)->getNameAsString();
+    }
+    Out << ")";
+
+    // Check the semantic DC.
+    const DeclContext* SemaDC = D->getDeclContext();
+    const DeclContext* LexicalDC = D->getLexicalDeclContext();
+    if (SemaDC != LexicalDC)
+      Out << " [[" << SemaDC << "]]";
+    break;
+  }
+  case Decl::CXXDestructor: {
+    const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC);
+    if (D->isOutOfLineDefinition())
+      Out << "[c++ dtor] ";
+    else if (D->isImplicit())
+      Out << "(c++ dtor) ";
+    else
+      Out << "<c++ dtor> ";
+    Out << D->getNameAsString();
+    // Check the semantic DC.
+    const DeclContext* SemaDC = D->getDeclContext();
+    const DeclContext* LexicalDC = D->getLexicalDeclContext();
+    if (SemaDC != LexicalDC)
+      Out << " [[" << SemaDC << "]]";
+    break;
+  }
+  case Decl::CXXConversion: {
+    const CXXConversionDecl* D = cast<CXXConversionDecl>(DC);
+    if (D->isOutOfLineDefinition())
+      Out << "[c++ conversion] ";
+    else if (D->isImplicit())
+      Out << "(c++ conversion) ";
+    else
+      Out << "<c++ conversion> ";
+    Out << D->getNameAsString();
+    // Check the semantic DC.
+    const DeclContext* SemaDC = D->getDeclContext();
+    const DeclContext* LexicalDC = D->getLexicalDeclContext();
+    if (SemaDC != LexicalDC)
+      Out << " [[" << SemaDC << "]]";
+    break;
+  }
+
+  default:
+    assert(0 && "a decl that inherits DeclContext isn't handled");
+  }
+
+  Out << "\n";
+
+  // Print decls in the DeclContext.
+  // FIXME: Should not use a NULL DeclContext!
+  ASTContext *Context = 0;
+  for (DeclContext::decl_iterator I = DC->decls_begin(*Context), 
+         E = DC->decls_end(*Context);
+       I != E; ++I) {
+    for (unsigned i = 0; i < Indentation; ++i)
+      Out << "  ";
+
+    Decl::Kind DK = I->getKind();
+    switch (DK) {
+    case Decl::Namespace:
+    case Decl::Enum:
+    case Decl::Record:
+    case Decl::CXXRecord:
+    case Decl::ObjCMethod:
+    case Decl::ObjCInterface:
+    case Decl::ObjCCategory: 
+    case Decl::ObjCProtocol:
+    case Decl::ObjCImplementation:
+    case Decl::ObjCCategoryImpl:
+    case Decl::LinkageSpec:
+    case Decl::Block:
+    case Decl::Function:
+    case Decl::CXXMethod:
+    case Decl::CXXConstructor:
+    case Decl::CXXDestructor:
+    case Decl::CXXConversion:
+    {
+      DeclContext* DC = cast<DeclContext>(*I);
+      PrintDeclContext(DC, Indentation+2);
+      break;
+    }
+    case Decl::Field: {
+      FieldDecl* FD = cast<FieldDecl>(*I);
+      Out << "<field> " << FD->getNameAsString() << "\n";
+      break;
+    }
+    case Decl::Typedef: {
+      TypedefDecl* TD = cast<TypedefDecl>(*I);
+      Out << "<typedef> " << TD->getNameAsString() << "\n";
+      break;
+    }
+    case Decl::EnumConstant: {
+      EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I);
+      Out << "<enum constant> " << ECD->getNameAsString() << "\n";
+      break;
+    }
+    case Decl::Var: {
+      VarDecl* VD = cast<VarDecl>(*I);
+      Out << "<var> " << VD->getNameAsString() << "\n";
+      break;
+    }
+    case Decl::ImplicitParam: {
+      ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I);
+      Out << "<implicit parameter> " << IPD->getNameAsString() << "\n";
+      break;
+    }
+    case Decl::ParmVar: {
+      ParmVarDecl* PVD = cast<ParmVarDecl>(*I);
+      Out << "<parameter> " << PVD->getNameAsString() << "\n";
+      break;
+    }
+    case Decl::OriginalParmVar: {
+      OriginalParmVarDecl* OPVD = cast<OriginalParmVarDecl>(*I);
+      Out << "<original parameter> " << OPVD->getNameAsString() << "\n";
+      break;
+    }
+    case Decl::ObjCProperty: {
+      ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I);
+      Out << "<objc property> " << OPD->getNameAsString() << "\n";
+      break;
+    }
+    default:
+      fprintf(stderr, "DeclKind: %d \"%s\"\n", DK, I->getDeclKindName());
+      assert(0 && "decl unhandled");
+    }
+  }
+}
+ASTConsumer *clang::CreateDeclContextPrinter() { 
+  return new DeclContextPrinter(); 
+}
+
+//===----------------------------------------------------------------------===//
+/// InheritanceViewer - C++ Inheritance Visualization
+
+namespace {
+class InheritanceViewer : public ASTConsumer {
+  const std::string clsname;
+public:
+  InheritanceViewer(const std::string& cname) : clsname(cname) {}
+  
+  void HandleTranslationUnit(ASTContext &C) {
+    for (ASTContext::type_iterator I=C.types_begin(),E=C.types_end(); I!=E; ++I)
+      if (RecordType *T = dyn_cast<RecordType>(*I)) {
+        if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(T->getDecl())) {
+          // FIXME: This lookup needs to be generalized to handle namespaces and
+          // (when we support them) templates.
+          if (D->getNameAsString() == clsname) {
+            D->viewInheritance(C);      
+          }
+        }
+      }
+  }
+}; 
+}
+
+ASTConsumer *clang::CreateInheritanceViewer(const std::string& clsname) {
+  return new InheritanceViewer(clsname);
+}
diff --git a/lib/Frontend/Backend.cpp b/lib/Frontend/Backend.cpp
new file mode 100644
index 0000000..259713f
--- /dev/null
+++ b/lib/Frontend/Backend.cpp
@@ -0,0 +1,414 @@
+//===--- Backend.cpp - Interface to LLVM backend technologies -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Frontend/CompileOptions.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/PassManager.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/CodeGen/RegAllocRegistry.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/System/Path.h"
+#include "llvm/System/Program.h"
+#include "llvm/Target/SubtargetFeature.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetMachineRegistry.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/IPO.h"
+using namespace clang;
+using namespace llvm;
+
+namespace {
+  class VISIBILITY_HIDDEN BackendConsumer : public ASTConsumer {
+    BackendAction Action;
+    CompileOptions CompileOpts;
+    llvm::raw_ostream *AsmOutStream;
+    ASTContext *Context;
+
+    Timer LLVMIRGeneration;
+    Timer CodeGenerationTime;
+    
+    llvm::OwningPtr<CodeGenerator> Gen;
+    
+    llvm::Module *TheModule;
+    llvm::TargetData *TheTargetData;
+
+    mutable llvm::ModuleProvider *ModuleProvider;
+    mutable FunctionPassManager *CodeGenPasses;
+    mutable PassManager *PerModulePasses;
+    mutable FunctionPassManager *PerFunctionPasses;
+
+    FunctionPassManager *getCodeGenPasses() const;
+    PassManager *getPerModulePasses() const;
+    FunctionPassManager *getPerFunctionPasses() const;
+
+    void CreatePasses();
+
+    /// AddEmitPasses - Add passes necessary to emit assembly or LLVM
+    /// IR.
+    ///
+    /// \return True on success. On failure \arg Error will be set to
+    /// a user readable error message.
+    bool AddEmitPasses(std::string &Error);
+
+    void EmitAssembly();
+    
+  public:  
+    BackendConsumer(BackendAction action, Diagnostic &Diags, 
+                    const LangOptions &langopts, const CompileOptions &compopts,
+                    const std::string &infile, llvm::raw_ostream* OS) :
+      Action(action), 
+      CompileOpts(compopts),
+      AsmOutStream(OS), 
+      LLVMIRGeneration("LLVM IR Generation Time"),
+      CodeGenerationTime("Code Generation Time"),
+      Gen(CreateLLVMCodeGen(Diags, infile, compopts)),
+      TheModule(0), TheTargetData(0), ModuleProvider(0),
+      CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
+      
+      // Enable -time-passes if -ftime-report is enabled.
+      llvm::TimePassesIsEnabled = CompileOpts.TimePasses;
+    }
+
+    ~BackendConsumer() {
+      delete TheTargetData;
+      delete ModuleProvider;
+      delete CodeGenPasses;
+      delete PerModulePasses;
+      delete PerFunctionPasses;
+    }
+
+    virtual void Initialize(ASTContext &Ctx) {
+      Context = &Ctx;
+      
+      if (CompileOpts.TimePasses)
+        LLVMIRGeneration.startTimer();
+      
+      Gen->Initialize(Ctx);
+
+      TheModule = Gen->GetModule();
+      ModuleProvider = new ExistingModuleProvider(TheModule);
+      TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription());
+      
+      if (CompileOpts.TimePasses)
+        LLVMIRGeneration.stopTimer();
+    }
+    
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
+                                     Context->getSourceManager(),
+                                     "LLVM IR generation of declaration");
+      
+      if (CompileOpts.TimePasses)
+        LLVMIRGeneration.startTimer();
+
+      Gen->HandleTopLevelDecl(D);
+
+      if (CompileOpts.TimePasses)
+        LLVMIRGeneration.stopTimer();
+    }
+    
+    virtual void HandleTranslationUnit(ASTContext &C) {
+      {
+        PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
+        if (CompileOpts.TimePasses)
+          LLVMIRGeneration.startTimer();
+
+        Gen->HandleTranslationUnit(C);
+
+        if (CompileOpts.TimePasses)
+          LLVMIRGeneration.stopTimer();
+      }
+
+      // EmitAssembly times and registers crash info itself.
+      EmitAssembly();
+      
+      // Force a flush here in case we never get released.
+      if (AsmOutStream)
+        AsmOutStream->flush();
+    }
+    
+    virtual void HandleTagDeclDefinition(TagDecl *D) {
+      PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
+                                     Context->getSourceManager(),
+                                     "LLVM IR generation of declaration");
+      Gen->HandleTagDeclDefinition(D);
+    }
+
+    virtual void CompleteTentativeDefinition(VarDecl *D) {
+      Gen->CompleteTentativeDefinition(D);
+    }
+  };  
+}
+
+FunctionPassManager *BackendConsumer::getCodeGenPasses() const {
+  if (!CodeGenPasses) {
+    CodeGenPasses = new FunctionPassManager(ModuleProvider);
+    CodeGenPasses->add(new TargetData(*TheTargetData));
+  }
+
+  return CodeGenPasses;
+}
+
+PassManager *BackendConsumer::getPerModulePasses() const {
+  if (!PerModulePasses) {
+    PerModulePasses = new PassManager();
+    PerModulePasses->add(new TargetData(*TheTargetData));
+  }
+
+  return PerModulePasses;
+}
+
+FunctionPassManager *BackendConsumer::getPerFunctionPasses() const {
+  if (!PerFunctionPasses) {
+    PerFunctionPasses = new FunctionPassManager(ModuleProvider);
+    PerFunctionPasses->add(new TargetData(*TheTargetData));
+  }
+
+  return PerFunctionPasses;
+}
+
+bool BackendConsumer::AddEmitPasses(std::string &Error) {
+  if (Action == Backend_EmitNothing)
+    return true;
+
+  if (Action == Backend_EmitBC) {
+    getPerModulePasses()->add(createBitcodeWriterPass(*AsmOutStream));
+  } else if (Action == Backend_EmitLL) {
+    getPerModulePasses()->add(createPrintModulePass(AsmOutStream));
+  } else {
+    bool Fast = CompileOpts.OptimizationLevel == 0;
+
+    // Create the TargetMachine for generating code.
+    const TargetMachineRegistry::entry *TME = 
+      TargetMachineRegistry::getClosestStaticTargetForModule(*TheModule, Error);
+    if (!TME) {
+      Error = std::string("Unable to get target machine: ") + Error;
+      return false;
+    }
+
+    std::string FeaturesStr;
+    if (CompileOpts.CPU.size() || CompileOpts.Features.size()) {
+      SubtargetFeatures Features;
+      Features.setCPU(CompileOpts.CPU);
+      for (std::vector<std::string>::iterator 
+             it = CompileOpts.Features.begin(),
+             ie = CompileOpts.Features.end(); it != ie; ++it)
+        Features.AddFeature(*it);
+      FeaturesStr = Features.getString();
+    }
+    TargetMachine *TM = TME->CtorFn(*TheModule, FeaturesStr);
+    
+    // Set register scheduler & allocation policy.
+    RegisterScheduler::setDefault(createDefaultScheduler);
+    RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator : 
+                                 createLinearScanRegisterAllocator);  
+
+    // From llvm-gcc:
+    // If there are passes we have to run on the entire module, we do codegen
+    // as a separate "pass" after that happens.
+    // FIXME: This is disabled right now until bugs can be worked out.  Reenable
+    // this for fast -O0 compiles!
+    FunctionPassManager *PM = getCodeGenPasses();
+    CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
+
+    switch (CompileOpts.OptimizationLevel) {
+    default: break;
+    case 0: OptLevel = CodeGenOpt::None; break;
+    case 3: OptLevel = CodeGenOpt::Aggressive; break;
+    }
+
+    // Normal mode, emit a .s file by running the code generator.
+    // Note, this also adds codegenerator level optimization passes.
+    switch (TM->addPassesToEmitFile(*PM, *AsmOutStream,
+                                    TargetMachine::AssemblyFile, OptLevel)) {
+    default:
+    case FileModel::Error:
+      Error = "Unable to interface with target machine!\n";
+      return false;
+    case FileModel::AsmFile:
+      break;
+    }
+    
+    if (TM->addPassesToEmitFileFinish(*CodeGenPasses, 0, OptLevel)) {
+      Error = "Unable to interface with target machine!\n";
+      return false;
+    }
+  }
+
+  return true;
+}
+
+void BackendConsumer::CreatePasses() {
+  // In -O0 if checking is disabled, we don't even have per-function passes.
+  if (CompileOpts.VerifyModule)
+    getPerFunctionPasses()->add(createVerifierPass());
+
+  if (CompileOpts.OptimizationLevel > 0) {
+    FunctionPassManager *PM = getPerFunctionPasses();
+    PM->add(createCFGSimplificationPass());
+    if (CompileOpts.OptimizationLevel == 1)
+      PM->add(createPromoteMemoryToRegisterPass());
+    else
+      PM->add(createScalarReplAggregatesPass());
+    PM->add(createInstructionCombiningPass());
+  }
+
+  // For now we always create per module passes.
+  PassManager *PM = getPerModulePasses();
+  if (CompileOpts.OptimizationLevel > 0) {
+    if (CompileOpts.UnitAtATime)
+      PM->add(createRaiseAllocationsPass());      // call %malloc -> malloc inst
+    PM->add(createCFGSimplificationPass());       // Clean up disgusting code
+    PM->add(createPromoteMemoryToRegisterPass()); // Kill useless allocas
+    if (CompileOpts.UnitAtATime) {
+      PM->add(createGlobalOptimizerPass());       // Optimize out global vars
+      PM->add(createGlobalDCEPass());             // Remove unused fns and globs
+      PM->add(createIPConstantPropagationPass()); // IP Constant Propagation
+      PM->add(createDeadArgEliminationPass());    // Dead argument elimination
+    }
+    PM->add(createInstructionCombiningPass());    // Clean up after IPCP & DAE
+    PM->add(createCFGSimplificationPass());       // Clean up after IPCP & DAE
+    if (CompileOpts.UnitAtATime) {
+      PM->add(createPruneEHPass());               // Remove dead EH info
+      PM->add(createFunctionAttrsPass());         // Set readonly/readnone attrs
+    }
+    if (CompileOpts.InlineFunctions)
+      PM->add(createFunctionInliningPass());      // Inline small functions
+    else 
+      PM->add(createAlwaysInlinerPass());         // Respect always_inline
+    if (CompileOpts.OptimizationLevel > 2)
+      PM->add(createArgumentPromotionPass());     // Scalarize uninlined fn args
+    if (CompileOpts.SimplifyLibCalls)
+      PM->add(createSimplifyLibCallsPass());      // Library Call Optimizations
+    PM->add(createInstructionCombiningPass());    // Cleanup for scalarrepl.
+    PM->add(createJumpThreadingPass());           // Thread jumps.
+    PM->add(createCFGSimplificationPass());       // Merge & remove BBs
+    PM->add(createScalarReplAggregatesPass());    // Break up aggregate allocas
+    PM->add(createInstructionCombiningPass());    // Combine silly seq's
+    PM->add(createCondPropagationPass());         // Propagate conditionals
+    PM->add(createTailCallEliminationPass());     // Eliminate tail calls
+    PM->add(createCFGSimplificationPass());       // Merge & remove BBs
+    PM->add(createReassociatePass());             // Reassociate expressions
+    PM->add(createLoopRotatePass());              // Rotate Loop
+    PM->add(createLICMPass());                    // Hoist loop invariants
+    PM->add(createLoopUnswitchPass(CompileOpts.OptimizeSize ? true : false));
+//    PM->add(createLoopIndexSplitPass());          // Split loop index
+    PM->add(createInstructionCombiningPass());  
+    PM->add(createIndVarSimplifyPass());          // Canonicalize indvars
+    PM->add(createLoopDeletionPass());            // Delete dead loops
+    if (CompileOpts.UnrollLoops)
+      PM->add(createLoopUnrollPass());            // Unroll small loops
+    PM->add(createInstructionCombiningPass());    // Clean up after the unroller
+    PM->add(createGVNPass());                     // Remove redundancies
+    PM->add(createMemCpyOptPass());               // Remove memcpy / form memset
+    PM->add(createSCCPPass());                    // Constant prop with SCCP
+    
+    // Run instcombine after redundancy elimination to exploit opportunities
+    // opened up by them.
+    PM->add(createInstructionCombiningPass());
+    PM->add(createCondPropagationPass());         // Propagate conditionals
+    PM->add(createDeadStoreEliminationPass());    // Delete dead stores
+    PM->add(createAggressiveDCEPass());           // Delete dead instructions
+    PM->add(createCFGSimplificationPass());       // Merge & remove BBs
+
+    if (CompileOpts.UnitAtATime) {
+      PM->add(createStripDeadPrototypesPass());   // Get rid of dead prototypes
+      PM->add(createDeadTypeEliminationPass());   // Eliminate dead types
+    }
+
+    if (CompileOpts.OptimizationLevel > 1 && CompileOpts.UnitAtATime)
+      PM->add(createConstantMergePass());         // Merge dup global constants 
+  } else {
+    PM->add(createAlwaysInlinerPass());  
+  }
+}
+
+/// EmitAssembly - Handle interaction with LLVM backend to generate
+/// actual machine code. 
+void BackendConsumer::EmitAssembly() {
+  // Silently ignore if we weren't initialized for some reason.
+  if (!TheModule || !TheTargetData)
+    return;
+  
+  
+  TimeRegion Region(CompileOpts.TimePasses ? &CodeGenerationTime : 0);
+
+  // Make sure IR generation is happy with the module. This is
+  // released by the module provider.
+  Module *M = Gen->ReleaseModule();
+  if (!M) {
+    // The module has been released by IR gen on failures, do not
+    // double free.
+    ModuleProvider->releaseModule();
+    TheModule = 0;
+    return;
+  }
+
+  assert(TheModule == M && "Unexpected module change during IR generation");
+
+  CreatePasses();
+
+  std::string Error;
+  if (!AddEmitPasses(Error)) {
+    // FIXME: Don't fail this way.
+    llvm::cerr << "ERROR: " << Error << "\n";
+    ::exit(1);
+  }
+
+  // Run passes. For now we do all passes at once, but eventually we
+  // would like to have the option of streaming code generation.
+
+  if (PerFunctionPasses) {
+    PrettyStackTraceString CrashInfo("Per-function optimization");
+    
+    PerFunctionPasses->doInitialization();
+    for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+      if (!I->isDeclaration())
+        PerFunctionPasses->run(*I);
+    PerFunctionPasses->doFinalization();
+  }
+  
+  if (PerModulePasses) {
+    PrettyStackTraceString CrashInfo("Per-module optimization passes");
+    PerModulePasses->run(*M);
+  }
+  
+  if (CodeGenPasses) {
+    PrettyStackTraceString CrashInfo("Code generation");
+    CodeGenPasses->doInitialization();
+    for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+      if (!I->isDeclaration())
+        CodeGenPasses->run(*I);
+    CodeGenPasses->doFinalization();
+  }
+}
+
+ASTConsumer *clang::CreateBackendConsumer(BackendAction Action,
+                                          Diagnostic &Diags,
+                                          const LangOptions &LangOpts,
+                                          const CompileOptions &CompileOpts,
+                                          const std::string& InFile,
+                                          llvm::raw_ostream* OS) {
+  return new BackendConsumer(Action, Diags, LangOpts, CompileOpts, InFile, OS);
+}
diff --git a/lib/Frontend/GeneratePCH.cpp b/lib/Frontend/GeneratePCH.cpp
new file mode 100644
index 0000000..8be88ce
--- /dev/null
+++ b/lib/Frontend/GeneratePCH.cpp
@@ -0,0 +1,78 @@
+//===--- GeneratePCH.cpp - AST Consumer for PCH Generation ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CreatePCHGenerate function, which creates an
+//  ASTConsume that generates a PCH file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/PCHWriter.h"
+#include "clang/Sema/SemaConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/FileManager.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/System/Path.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Streams.h"
+#include <string>
+
+using namespace clang;
+using namespace llvm;
+
+namespace {
+  class VISIBILITY_HIDDEN PCHGenerator : public SemaConsumer {
+    const Preprocessor &PP;
+    llvm::raw_ostream *Out;
+    Sema *SemaPtr;
+    MemorizeStatCalls *StatCalls; // owned by the FileManager
+
+  public:
+    explicit PCHGenerator(const Preprocessor &PP, llvm::raw_ostream *Out);
+    virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
+    virtual void HandleTranslationUnit(ASTContext &Ctx);
+  };
+}
+
+PCHGenerator::PCHGenerator(const Preprocessor &PP, llvm::raw_ostream *OS)
+  : PP(PP), Out(OS), SemaPtr(0), StatCalls(0) { 
+
+  // Install a stat() listener to keep track of all of the stat()
+  // calls.
+  StatCalls = new MemorizeStatCalls;
+  PP.getFileManager().setStatCache(StatCalls);
+}
+
+void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
+  if (PP.getDiagnostics().hasErrorOccurred())
+    return;
+
+ // Write the PCH contents into a buffer
+  std::vector<unsigned char> Buffer;
+  BitstreamWriter Stream(Buffer);
+  PCHWriter Writer(Stream);
+
+  // Emit the PCH file
+  assert(SemaPtr && "No Sema?");
+  Writer.WritePCH(*SemaPtr, StatCalls);
+
+  // Write the generated bitstream to "Out".
+  Out->write((char *)&Buffer.front(), Buffer.size());
+
+  // Make sure it hits disk now.
+  Out->flush();
+}
+
+ASTConsumer *clang::CreatePCHGenerator(const Preprocessor &PP,
+                                       llvm::raw_ostream *OS) {
+  return new PCHGenerator(PP, OS);
+}
diff --git a/lib/Frontend/HTMLPrint.cpp b/lib/Frontend/HTMLPrint.cpp
new file mode 100644
index 0000000..a4ce9e5
--- /dev/null
+++ b/lib/Frontend/HTMLPrint.cpp
@@ -0,0 +1,83 @@
+//===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Pretty-printing of source code to HTML.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/Decl.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "clang/Rewrite/HTMLRewrite.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/AST/ASTContext.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Functional HTML pretty-printing.
+//===----------------------------------------------------------------------===//  
+
+namespace {
+  class HTMLPrinter : public ASTConsumer {
+    Rewriter R;
+    llvm::raw_ostream *Out;
+    Diagnostic &Diags;
+    Preprocessor *PP;
+    PreprocessorFactory *PPF;
+  public:
+    HTMLPrinter(llvm::raw_ostream *OS, Diagnostic &D, Preprocessor *pp,
+                PreprocessorFactory* ppf)
+      : Out(OS), Diags(D), PP(pp), PPF(ppf) {}
+    virtual ~HTMLPrinter();
+    
+    void Initialize(ASTContext &context);
+  };
+}
+
+ASTConsumer* clang::CreateHTMLPrinter(llvm::raw_ostream *OS,
+                                      Diagnostic &D, Preprocessor *PP,
+                                      PreprocessorFactory* PPF) {
+  
+  return new HTMLPrinter(OS, D, PP, PPF);
+}
+
+void HTMLPrinter::Initialize(ASTContext &context) {
+  R.setSourceMgr(context.getSourceManager(), context.getLangOptions());
+}
+
+HTMLPrinter::~HTMLPrinter() {
+  if (Diags.hasErrorOccurred())
+    return;
+
+  // Format the file.
+  FileID FID = R.getSourceMgr().getMainFileID();
+  const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID);
+  
+  html::AddLineNumbers(R, FID);
+  html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName());
+
+  // If we have a preprocessor, relex the file and syntax highlight.
+  // We might not have a preprocessor if we come from a deserialized AST file,
+  // for example.
+  
+  if (PP) html::SyntaxHighlight(R, FID, *PP);
+  if (PPF) html::HighlightMacros(R, FID, *PP);
+  html::EscapeText(R, FID, false, true);
+
+  // Emit the HTML.
+  const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
+  char *Buffer = (char*)malloc(RewriteBuf.size());
+  std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
+  Out->write(Buffer, RewriteBuf.size());
+  free(Buffer);
+}
diff --git a/lib/Frontend/RewriteBlocks.cpp b/lib/Frontend/RewriteBlocks.cpp
new file mode 100644
index 0000000..29f0578
--- /dev/null
+++ b/lib/Frontend/RewriteBlocks.cpp
@@ -0,0 +1,1158 @@
+//===--- RewriteBlocks.cpp ----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Hacks and fun related to the closure rewriter.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <sstream>
+
+using namespace clang;
+using llvm::utostr;
+
+namespace {
+
+class RewriteBlocks : public ASTConsumer {
+  Rewriter Rewrite;
+  Diagnostic &Diags;
+  const LangOptions &LangOpts;
+  unsigned RewriteFailedDiag;
+
+  ASTContext *Context;
+  SourceManager *SM;
+  FileID MainFileID;
+  const char *MainFileStart, *MainFileEnd;
+
+  // Block expressions.
+  llvm::SmallVector<BlockExpr *, 32> Blocks;
+  llvm::SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs;
+  llvm::DenseMap<BlockDeclRefExpr *, CallExpr *> BlockCallExprs;
+  
+  // Block related declarations.
+  llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDecls;
+  llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDecls;
+  llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
+
+  llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
+  
+  // The function/method we are rewriting.
+  FunctionDecl *CurFunctionDef;
+  ObjCMethodDecl *CurMethodDef;
+  
+  bool IsHeader;
+  
+  std::string Preamble;
+public:
+  RewriteBlocks(std::string inFile, Diagnostic &D, 
+                const LangOptions &LOpts);
+  ~RewriteBlocks() {
+    // Get the buffer corresponding to MainFileID.  
+    // If we haven't changed it, then we are done.
+    if (const RewriteBuffer *RewriteBuf = 
+        Rewrite.getRewriteBufferFor(MainFileID)) {
+      std::string S(RewriteBuf->begin(), RewriteBuf->end());
+      printf("%s\n", S.c_str());
+    } else {
+      printf("No changes\n");
+    }
+  }
+  
+  void Initialize(ASTContext &context);
+
+  void InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen);
+  void ReplaceText(SourceLocation Start, unsigned OrigLength,
+                   const char *NewStr, unsigned NewLength);
+
+  // Top Level Driver code.
+  virtual void HandleTopLevelDecl(DeclGroupRef D) {
+    for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+      HandleTopLevelSingleDecl(*I);
+  }
+  void HandleTopLevelSingleDecl(Decl *D);
+  void HandleDeclInMainFile(Decl *D);
+  
+  // Top level 
+  Stmt *RewriteFunctionBody(Stmt *S);
+  void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
+  void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
+  
+  // Block specific rewrite rules.
+  std::string SynthesizeBlockInitExpr(BlockExpr *Exp, VarDecl *VD=0);
+  
+  void RewriteBlockCall(CallExpr *Exp);
+  void RewriteBlockPointerDecl(NamedDecl *VD);
+  void RewriteBlockDeclRefExpr(BlockDeclRefExpr *VD);
+  void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
+  
+  std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 
+                                    const char *funcName, std::string Tag);
+  std::string SynthesizeBlockFunc(BlockExpr *CE, int i, 
+                                    const char *funcName, std::string Tag);
+  std::string SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
+                                  bool hasCopyDisposeHelpers);
+  std::string SynthesizeBlockCall(CallExpr *Exp);
+  void SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                 const char *FunName);
+  
+  void CollectBlockDeclRefInfo(BlockExpr *Exp);
+  void GetBlockCallExprs(Stmt *S);
+  void GetBlockDeclRefExprs(Stmt *S);
+  
+  // We avoid calling Type::isBlockPointerType(), since it operates on the
+  // canonical type. We only care if the top-level type is a closure pointer.
+  bool isBlockPointerType(QualType T) { return isa<BlockPointerType>(T); }
+  
+  // FIXME: This predicate seems like it would be useful to add to ASTContext.
+  bool isObjCType(QualType T) {
+    if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
+      return false;
+      
+    QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
+    
+    if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
+        OCT == Context->getCanonicalType(Context->getObjCClassType()))
+      return true;
+      
+    if (const PointerType *PT = OCT->getAsPointerType()) {
+      if (isa<ObjCInterfaceType>(PT->getPointeeType()) || 
+          isa<ObjCQualifiedIdType>(PT->getPointeeType()))
+        return true;
+    }
+    return false;
+  }
+  // ObjC rewrite methods.
+  void RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl);
+  void RewriteCategoryDecl(ObjCCategoryDecl *CatDecl);
+  void RewriteProtocolDecl(ObjCProtocolDecl *PDecl);
+  void RewriteMethodDecl(ObjCMethodDecl *MDecl);
+
+  void RewriteFunctionProtoType(QualType funcType, NamedDecl *D);
+  void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
+  void RewriteCastExpr(CastExpr *CE);
+  
+  bool PointerTypeTakesAnyBlockArguments(QualType QT);
+  void GetExtentOfArgList(const char *Name, const char *&LParen, const char *&RParen);
+};
+  
+}
+
+static bool IsHeaderFile(const std::string &Filename) {
+  std::string::size_type DotPos = Filename.rfind('.');
+  
+  if (DotPos == std::string::npos) {
+    // no file extension
+    return false; 
+  }
+  
+  std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
+  // C header: .h
+  // C++ header: .hh or .H;
+  return Ext == "h" || Ext == "hh" || Ext == "H";
+}    
+
+RewriteBlocks::RewriteBlocks(std::string inFile,
+                             Diagnostic &D, const LangOptions &LOpts) : 
+  Diags(D), LangOpts(LOpts) {
+  IsHeader = IsHeaderFile(inFile);
+  CurFunctionDef = 0;
+  CurMethodDef = 0;
+  RewriteFailedDiag = Diags.getCustomDiagID(Diagnostic::Warning, 
+                                            "rewriting failed");
+}
+
+ASTConsumer *clang::CreateBlockRewriter(const std::string& InFile,
+                                        Diagnostic &Diags,
+                                        const LangOptions &LangOpts) {
+  return new RewriteBlocks(InFile, Diags, LangOpts);
+}
+
+void RewriteBlocks::Initialize(ASTContext &context) {
+  Context = &context;
+  SM = &Context->getSourceManager();
+  
+  // Get the ID and start/end of the main file.
+  MainFileID = SM->getMainFileID();
+  const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
+  MainFileStart = MainBuf->getBufferStart();
+  MainFileEnd = MainBuf->getBufferEnd();
+  
+  Rewrite.setSourceMgr(Context->getSourceManager(), LangOpts);
+  
+  if (IsHeader)
+    Preamble = "#pragma once\n";
+  Preamble += "#ifndef BLOCK_IMPL\n";
+  Preamble += "#define BLOCK_IMPL\n";
+  Preamble += "struct __block_impl {\n";
+  Preamble += "  void *isa;\n";
+  Preamble += "  int Flags;\n";
+  Preamble += "  int Size;\n";
+  Preamble += "  void *FuncPtr;\n";
+  Preamble += "};\n";
+  Preamble += "enum {\n";
+  Preamble += "  BLOCK_HAS_COPY_DISPOSE = (1<<25),\n";
+  Preamble += "  BLOCK_IS_GLOBAL = (1<<28)\n";
+  Preamble += "};\n";
+  if (LangOpts.Microsoft) 
+    Preamble += "#define __OBJC_RW_EXTERN extern \"C\" __declspec(dllimport)\n";
+  else
+    Preamble += "#define __OBJC_RW_EXTERN extern\n";
+  Preamble += "// Runtime copy/destroy helper functions\n";
+  Preamble += "__OBJC_RW_EXTERN void _Block_copy_assign(void *, void *);\n";
+  Preamble += "__OBJC_RW_EXTERN void _Block_byref_assign_copy(void *, void *);\n";
+  Preamble += "__OBJC_RW_EXTERN void _Block_destroy(void *);\n";
+  Preamble += "__OBJC_RW_EXTERN void _Block_byref_release(void *);\n";
+  Preamble += "__OBJC_RW_EXTERN void *_NSConcreteGlobalBlock;\n";
+  Preamble += "__OBJC_RW_EXTERN void *_NSConcreteStackBlock;\n";
+  Preamble += "#endif\n";
+  
+  InsertText(SM->getLocForStartOfFile(MainFileID), 
+             Preamble.c_str(), Preamble.size());
+}
+
+void RewriteBlocks::InsertText(SourceLocation Loc, const char *StrData, 
+                                 unsigned StrLen)
+{
+  if (!Rewrite.InsertText(Loc, StrData, StrLen))
+    return;
+  Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
+}
+
+void RewriteBlocks::ReplaceText(SourceLocation Start, unsigned OrigLength,
+                                  const char *NewStr, unsigned NewLength) {
+  if (!Rewrite.ReplaceText(Start, OrigLength, NewStr, NewLength))
+    return;
+  Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
+}
+
+void RewriteBlocks::RewriteMethodDecl(ObjCMethodDecl *Method) {
+  bool haveBlockPtrs = false;
+  for (ObjCMethodDecl::param_iterator I = Method->param_begin(), 
+       E = Method->param_end(); I != E; ++I)
+    if (isBlockPointerType((*I)->getType()))
+      haveBlockPtrs = true;
+      
+  if (!haveBlockPtrs)
+    return;
+    
+  // Do a fuzzy rewrite.
+  // We have 1 or more arguments that have closure pointers.
+  SourceLocation Loc = Method->getLocStart();
+  SourceLocation LocEnd = Method->getLocEnd();
+  const char *startBuf = SM->getCharacterData(Loc);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+
+  const char *methodPtr = startBuf;
+  std::string Tag = "struct __block_impl *";
+  
+  while (*methodPtr++ && (methodPtr != endBuf)) {
+    switch (*methodPtr) {
+      case ':':
+        methodPtr++;
+        if (*methodPtr == '(') {
+          const char *scanType = ++methodPtr;
+          bool foundBlockPointer = false;
+          unsigned parenCount = 1;
+          
+          while (parenCount) {
+            switch (*scanType) {
+              case '(': 
+                parenCount++; 
+                break;
+              case ')': 
+                parenCount--;
+                break;
+              case '^':
+                foundBlockPointer = true;
+                break;
+            }
+            scanType++;
+          }
+          if (foundBlockPointer) {
+            // advance the location to startArgList.
+            Loc = Loc.getFileLocWithOffset(methodPtr-startBuf);
+            assert((Loc.isValid()) && "Invalid Loc");
+            ReplaceText(Loc, scanType-methodPtr-1, Tag.c_str(), Tag.size());
+            
+            // Advance startBuf. Since the underlying buffer has changed,
+            // it's very important to advance startBuf (so we can correctly
+            // compute a relative Loc the next time around).
+            startBuf = methodPtr;
+          }
+          // Advance the method ptr to the end of the type.
+          methodPtr = scanType;
+        }
+        break;
+    }
+  }
+  return;
+}
+
+void RewriteBlocks::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
+  for (ObjCInterfaceDecl::instmeth_iterator 
+         I = ClassDecl->instmeth_begin(*Context), 
+         E = ClassDecl->instmeth_end(*Context); 
+       I != E; ++I)
+    RewriteMethodDecl(*I);
+  for (ObjCInterfaceDecl::classmeth_iterator 
+         I = ClassDecl->classmeth_begin(*Context), 
+         E = ClassDecl->classmeth_end(*Context);
+       I != E; ++I)
+    RewriteMethodDecl(*I);
+}
+
+void RewriteBlocks::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
+  for (ObjCCategoryDecl::instmeth_iterator 
+         I = CatDecl->instmeth_begin(*Context), 
+         E = CatDecl->instmeth_end(*Context); 
+       I != E; ++I)
+    RewriteMethodDecl(*I);
+  for (ObjCCategoryDecl::classmeth_iterator 
+         I = CatDecl->classmeth_begin(*Context), 
+         E = CatDecl->classmeth_end(*Context);
+       I != E; ++I)
+    RewriteMethodDecl(*I);
+}
+
+void RewriteBlocks::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
+  for (ObjCProtocolDecl::instmeth_iterator 
+         I = PDecl->instmeth_begin(*Context), 
+         E = PDecl->instmeth_end(*Context); 
+       I != E; ++I)
+    RewriteMethodDecl(*I);
+  for (ObjCProtocolDecl::classmeth_iterator 
+         I = PDecl->classmeth_begin(*Context), 
+         E = PDecl->classmeth_end(*Context); 
+       I != E; ++I)
+    RewriteMethodDecl(*I);
+}
+
+//===----------------------------------------------------------------------===//
+// Top Level Driver Code
+//===----------------------------------------------------------------------===//
+
+void RewriteBlocks::HandleTopLevelSingleDecl(Decl *D) {
+  // Two cases: either the decl could be in the main file, or it could be in a
+  // #included file.  If the former, rewrite it now.  If the later, check to see
+  // if we rewrote the #include/#import.
+  SourceLocation Loc = D->getLocation();
+  Loc = SM->getInstantiationLoc(Loc);
+  
+  // If this is for a builtin, ignore it.
+  if (Loc.isInvalid()) return;
+  
+  if (ObjCInterfaceDecl *MD = dyn_cast<ObjCInterfaceDecl>(D))
+    RewriteInterfaceDecl(MD);
+  else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D))
+    RewriteCategoryDecl(CD);
+  else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
+    RewriteProtocolDecl(PD);
+
+  // If we have a decl in the main file, see if we should rewrite it.
+  if (SM->isFromMainFile(Loc))
+    HandleDeclInMainFile(D);
+  return;
+}
+
+std::string RewriteBlocks::SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                                   const char *funcName,
+                                                   std::string Tag) {
+  const FunctionType *AFT = CE->getFunctionType();
+  QualType RT = AFT->getResultType();
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static " + RT.getAsString() + " __" +
+                  funcName + "_" + "block_func_" + utostr(i);
+
+  BlockDecl *BD = CE->getBlockDecl();
+  
+  if (isa<FunctionNoProtoType>(AFT)) {
+    S += "()";
+  } else if (BD->param_empty()) {
+    S += "(" + StructRef + " *__cself)";
+  } else {
+    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
+    assert(FT && "SynthesizeBlockFunc: No function proto");
+    S += '(';
+    // first add the implicit argument.
+    S += StructRef + " *__cself, ";
+    std::string ParamStr;
+    for (BlockDecl::param_iterator AI = BD->param_begin(),
+         E = BD->param_end(); AI != E; ++AI) {
+      if (AI != BD->param_begin()) S += ", ";
+      ParamStr = (*AI)->getNameAsString();
+      (*AI)->getType().getAsStringInternal(ParamStr);
+      S += ParamStr;
+    }
+    if (FT->isVariadic()) {
+      if (!BD->param_empty()) S += ", ";
+      S += "...";
+    }
+    S += ')';
+  }
+  S += " {\n";
+  
+  // Create local declarations to avoid rewriting all closure decl ref exprs.
+  // First, emit a declaration for all "by ref" decls.
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 
+       E = BlockByRefDecls.end(); I != E; ++I) {
+    S += "  ";
+    std::string Name = (*I)->getNameAsString();
+    Context->getPointerType((*I)->getType()).getAsStringInternal(Name);
+    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
+  }    
+  // Next, emit a declaration for all "by copy" declarations.
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 
+       E = BlockByCopyDecls.end(); I != E; ++I) {
+    S += "  ";
+    std::string Name = (*I)->getNameAsString();
+    // Handle nested closure invocation. For example:
+    //
+    //   void (^myImportedClosure)(void);
+    //   myImportedClosure  = ^(void) { setGlobalInt(x + y); };
+    // 
+    //   void (^anotherClosure)(void);
+    //   anotherClosure = ^(void) {
+    //     myImportedClosure(); // import and invoke the closure
+    //   };
+    //
+    if (isBlockPointerType((*I)->getType()))
+      S += "struct __block_impl *";
+    else
+      (*I)->getType().getAsStringInternal(Name);
+    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
+  }
+  std::string RewrittenStr = RewrittenBlockExprs[CE];
+  const char *cstr = RewrittenStr.c_str();
+  while (*cstr++ != '{') ;
+  S += cstr;
+  S += "\n";
+  return S;
+}
+
+std::string RewriteBlocks::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                                   const char *funcName,
+                                                   std::string Tag) {
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static void __";
+  
+  S += funcName;
+  S += "_block_copy_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*dst, " + StructRef;
+  S += "*src) {";
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 
+      E = ImportedBlockDecls.end(); I != E; ++I) {
+    S += "_Block_copy_assign(&dst->";
+    S += (*I)->getNameAsString();
+    S += ", src->";
+    S += (*I)->getNameAsString();
+    S += ");}";
+  }
+  S += "\nstatic void __";
+  S += funcName;
+  S += "_block_dispose_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*src) {";
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 
+      E = ImportedBlockDecls.end(); I != E; ++I) {
+    S += "_Block_destroy(src->";
+    S += (*I)->getNameAsString();
+    S += ");";
+  }
+  S += "}\n";  
+  return S;
+}
+
+std::string RewriteBlocks::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
+                                               bool hasCopyDisposeHelpers) {
+  std::string S = "struct " + Tag;
+  std::string Constructor = "  " + Tag;
+  
+  S += " {\n  struct __block_impl impl;\n";
+  
+  if (hasCopyDisposeHelpers)
+    S += "  void *copy;\n  void *dispose;\n";
+    
+  Constructor += "(void *fp";
+  
+  if (hasCopyDisposeHelpers)
+    Constructor += ", void *copyHelp, void *disposeHelp";
+    
+  if (BlockDeclRefs.size()) {
+    // Output all "by copy" declarations.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      // Handle nested closure invocation. For example:
+      //
+      //   void (^myImportedBlock)(void);
+      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
+      // 
+      //   void (^anotherBlock)(void);
+      //   anotherBlock = ^(void) {
+      //     myImportedBlock(); // import and invoke the closure
+      //   };
+      //
+      if (isBlockPointerType((*I)->getType())) {
+        S += "struct __block_impl *";
+        Constructor += ", void *" + ArgName;
+      } else {
+        (*I)->getType().getAsStringInternal(FieldName);
+        (*I)->getType().getAsStringInternal(ArgName);
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + ";\n";
+    }
+    // Output all "by ref" declarations.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      // Handle nested closure invocation. For example:
+      //
+      //   void (^myImportedBlock)(void);
+      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
+      // 
+      //   void (^anotherBlock)(void);
+      //   anotherBlock = ^(void) {
+      //     myImportedBlock(); // import and invoke the closure
+      //   };
+      //
+      if (isBlockPointerType((*I)->getType())) {
+        S += "struct __block_impl *";
+        Constructor += ", void *" + ArgName;
+      } else {
+        Context->getPointerType((*I)->getType()).getAsStringInternal(FieldName);
+        Context->getPointerType((*I)->getType()).getAsStringInternal(ArgName);
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + "; // by ref\n";
+    }
+    // Finish writing the constructor.
+    // FIXME: handle NSConcreteGlobalBlock.
+    Constructor += ", int flags=0) {\n";
+    Constructor += "    impl.isa = 0/*&_NSConcreteStackBlock*/;\n    impl.Size = sizeof(";
+    Constructor += Tag + ");\n    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+    
+    if (hasCopyDisposeHelpers)
+      Constructor += "    copy = copyHelp;\n    dispose = disposeHelp;\n";
+      
+    // Initialize all "by copy" arguments.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+      Constructor += "    ";
+      if (isBlockPointerType((*I)->getType()))
+        Constructor += Name + " = (struct __block_impl *)_";
+      else
+        Constructor += Name + " = _";
+      Constructor += Name + ";\n";
+    }
+    // Initialize all "by ref" arguments.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+      Constructor += "    ";
+      if (isBlockPointerType((*I)->getType()))
+        Constructor += Name + " = (struct __block_impl *)_";
+      else
+        Constructor += Name + " = _";
+      Constructor += Name + ";\n";
+    }
+  } else {
+    // Finish writing the constructor.
+    // FIXME: handle NSConcreteGlobalBlock.
+    Constructor += ", int flags=0) {\n";
+    Constructor += "    impl.isa = 0/*&_NSConcreteStackBlock*/;\n    impl.Size = sizeof(";
+    Constructor += Tag + ");\n    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+    if (hasCopyDisposeHelpers)
+      Constructor += "    copy = copyHelp;\n    dispose = disposeHelp;\n";
+  }
+  Constructor += "  ";
+  Constructor += "}\n";
+  S += Constructor;
+  S += "};\n";
+  return S;
+}
+
+void RewriteBlocks::SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                                const char *FunName) {
+  // Insert closures that were part of the function.
+  for (unsigned i = 0; i < Blocks.size(); i++) {
+
+    CollectBlockDeclRefInfo(Blocks[i]);
+
+    std::string Tag = "__" + std::string(FunName) + "_block_impl_" + utostr(i);
+                      
+    std::string CI = SynthesizeBlockImpl(Blocks[i], Tag, 
+                                         ImportedBlockDecls.size() > 0);
+
+    InsertText(FunLocStart, CI.c_str(), CI.size());
+
+    std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, Tag);
+    
+    InsertText(FunLocStart, CF.c_str(), CF.size());
+
+    if (ImportedBlockDecls.size()) {
+      std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, Tag);
+      InsertText(FunLocStart, HF.c_str(), HF.size());
+    }
+    
+    BlockDeclRefs.clear();
+    BlockByRefDecls.clear();
+    BlockByCopyDecls.clear();
+    BlockCallExprs.clear();
+    ImportedBlockDecls.clear();
+  }
+  Blocks.clear();
+  RewrittenBlockExprs.clear();
+}
+
+void RewriteBlocks::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
+  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
+  const char *FuncName = FD->getNameAsCString();
+  
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+void RewriteBlocks::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
+  SourceLocation FunLocStart = MD->getLocStart();
+  std::string FuncName = MD->getSelector().getAsString();
+  // Convert colons to underscores.
+  std::string::size_type loc = 0;
+  while ((loc = FuncName.find(":", loc)) != std::string::npos)
+    FuncName.replace(loc, 1, "_");
+  
+  SynthesizeBlockLiterals(FunLocStart, FuncName.c_str());
+}
+
+void RewriteBlocks::GetBlockDeclRefExprs(Stmt *S) {
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
+        GetBlockDeclRefExprs(CBE->getBody());
+      else
+        GetBlockDeclRefExprs(*CI);
+    }
+  // Handle specific things.
+  if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S))
+    // FIXME: Handle enums.
+    if (!isa<FunctionDecl>(CDRE->getDecl()))
+      BlockDeclRefs.push_back(CDRE);
+  return;
+}
+
+void RewriteBlocks::GetBlockCallExprs(Stmt *S) {
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
+        GetBlockCallExprs(CBE->getBody());
+      else
+        GetBlockCallExprs(*CI);
+    }
+      
+  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
+    if (CE->getCallee()->getType()->isBlockPointerType()) {
+      BlockCallExprs[dyn_cast<BlockDeclRefExpr>(CE->getCallee())] = CE;
+    }
+  }
+  return;
+}
+
+std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {
+  // Navigate to relevant type information.
+  const char *closureName = 0;
+  const BlockPointerType *CPT = 0;
+  
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp->getCallee())) {
+    closureName = DRE->getDecl()->getNameAsCString();
+    CPT = DRE->getType()->getAsBlockPointerType();
+  } else if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(Exp->getCallee())) {
+    closureName = CDRE->getDecl()->getNameAsCString();
+    CPT = CDRE->getType()->getAsBlockPointerType();
+  } else if (MemberExpr *MExpr = dyn_cast<MemberExpr>(Exp->getCallee())) {
+    closureName = MExpr->getMemberDecl()->getNameAsCString();
+    CPT = MExpr->getType()->getAsBlockPointerType();
+  } else {
+    assert(1 && "RewriteBlockClass: Bad type");
+  }
+  assert(CPT && "RewriteBlockClass: Bad type");
+  const FunctionType *FT = CPT->getPointeeType()->getAsFunctionType();
+  assert(FT && "RewriteBlockClass: Bad type");
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+  
+  // Build a closure call - start with a paren expr to enforce precedence.
+  std::string BlockCall = "(";
+
+  // Synthesize the cast.  
+  BlockCall += "(" + Exp->getType().getAsString() + "(*)";
+  BlockCall += "(struct __block_impl *";
+  if (FTP) {
+    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 
+         E = FTP->arg_type_end(); I && (I != E); ++I)
+      BlockCall += ", " + (*I).getAsString();
+  }
+  BlockCall += "))"; // close the argument list and paren expression.
+  
+  // Invoke the closure. We need to cast it since the declaration type is
+  // bogus (it's a function pointer type)
+  BlockCall += "((struct __block_impl *)";
+  std::string closureExprBufStr;
+  llvm::raw_string_ostream closureExprBuf(closureExprBufStr);
+  Exp->getCallee()->printPretty(closureExprBuf);
+  BlockCall += closureExprBuf.str();
+  BlockCall += ")->FuncPtr)";
+  
+  // Add the arguments.
+  BlockCall += "((struct __block_impl *)";
+  BlockCall += closureExprBuf.str();
+  for (CallExpr::arg_iterator I = Exp->arg_begin(), 
+       E = Exp->arg_end(); I != E; ++I) {
+    std::string syncExprBufS;
+    llvm::raw_string_ostream Buf(syncExprBufS);
+    (*I)->printPretty(Buf);
+    BlockCall += ", " + Buf.str();
+  }
+  return BlockCall;
+}
+
+void RewriteBlocks::RewriteBlockCall(CallExpr *Exp) {
+  std::string BlockCall = SynthesizeBlockCall(Exp);
+  
+  const char *startBuf = SM->getCharacterData(Exp->getLocStart());
+  const char *endBuf = SM->getCharacterData(Exp->getLocEnd());
+
+  ReplaceText(Exp->getLocStart(), endBuf-startBuf, 
+              BlockCall.c_str(), BlockCall.size());
+}
+
+void RewriteBlocks::RewriteBlockDeclRefExpr(BlockDeclRefExpr *BDRE) {
+  // FIXME: Add more elaborate code generation required by the ABI.
+  InsertText(BDRE->getLocStart(), "*", 1);
+}
+
+void RewriteBlocks::RewriteCastExpr(CastExpr *CE) {
+  SourceLocation LocStart = CE->getLocStart();
+  SourceLocation LocEnd = CE->getLocEnd();
+  
+  if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
+    return;
+    
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  
+  // advance the location to startArgList.
+  const char *argPtr = startBuf;
+  
+  while (*argPtr++ && (argPtr < endBuf)) {
+    switch (*argPtr) {
+      case '^': 
+        // Replace the '^' with '*'.
+        LocStart = LocStart.getFileLocWithOffset(argPtr-startBuf);
+        ReplaceText(LocStart, 1, "*", 1);
+        break;
+    }
+  }
+  return;
+}
+
+void RewriteBlocks::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
+  SourceLocation DeclLoc = FD->getLocation();
+  unsigned parenCount = 0;
+  
+  // We have 1 or more arguments that have closure pointers.
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *startArgList = strchr(startBuf, '(');
+  
+  assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
+  
+  parenCount++;
+  // advance the location to startArgList.
+  DeclLoc = DeclLoc.getFileLocWithOffset(startArgList-startBuf);
+  assert((DeclLoc.isValid()) && "Invalid DeclLoc");
+  
+  const char *argPtr = startArgList;
+  
+  while (*argPtr++ && parenCount) {
+    switch (*argPtr) {
+      case '^': 
+        // Replace the '^' with '*'.
+        DeclLoc = DeclLoc.getFileLocWithOffset(argPtr-startArgList);
+        ReplaceText(DeclLoc, 1, "*", 1);
+        break;
+      case '(': 
+        parenCount++; 
+        break;
+      case ')': 
+        parenCount--;
+        break;
+    }
+  }
+  return;
+}
+
+bool RewriteBlocks::PointerTypeTakesAnyBlockArguments(QualType QT) {
+  const FunctionProtoType *FTP;
+  const PointerType *PT = QT->getAsPointerType();
+  if (PT) {
+    FTP = PT->getPointeeType()->getAsFunctionProtoType();
+  } else {
+    const BlockPointerType *BPT = QT->getAsBlockPointerType();
+    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+    FTP = BPT->getPointeeType()->getAsFunctionProtoType();
+  }
+  if (FTP) {
+    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 
+         E = FTP->arg_type_end(); I != E; ++I)
+      if (isBlockPointerType(*I))
+        return true;
+  }
+  return false;
+}
+
+void RewriteBlocks::GetExtentOfArgList(const char *Name, 
+                                       const char *&LParen, const char *&RParen) {
+  const char *argPtr = strchr(Name, '(');
+  assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
+  
+  LParen = argPtr; // output the start.
+  argPtr++; // skip past the left paren.
+  unsigned parenCount = 1;
+  
+  while (*argPtr && parenCount) {
+    switch (*argPtr) {
+      case '(': parenCount++; break;
+      case ')': parenCount--; break;
+      default: break;
+    }
+    if (parenCount) argPtr++;
+  }
+  assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
+  RParen = argPtr; // output the end
+}
+
+void RewriteBlocks::RewriteBlockPointerDecl(NamedDecl *ND) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+    RewriteBlockPointerFunctionArgs(FD);
+    return;
+  } 
+  // Handle Variables and Typedefs.
+  SourceLocation DeclLoc = ND->getLocation();
+  QualType DeclT;
+  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
+    DeclT = VD->getType();
+  else if (TypedefDecl *TDD = dyn_cast<TypedefDecl>(ND))
+    DeclT = TDD->getUnderlyingType();
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
+    DeclT = FD->getType();
+  else 
+    assert(0 && "RewriteBlockPointerDecl(): Decl type not yet handled");
+    
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *endBuf = startBuf;
+  // scan backward (from the decl location) for the end of the previous decl.
+  while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
+    startBuf--;
+    
+  // *startBuf != '^' if we are dealing with a pointer to function that
+  // may take block argument types (which will be handled below).
+  if (*startBuf == '^') {
+    // Replace the '^' with '*', computing a negative offset.
+    DeclLoc = DeclLoc.getFileLocWithOffset(startBuf-endBuf);
+    ReplaceText(DeclLoc, 1, "*", 1);
+  }
+  if (PointerTypeTakesAnyBlockArguments(DeclT)) {
+    // Replace the '^' with '*' for arguments.
+    DeclLoc = ND->getLocation();
+    startBuf = SM->getCharacterData(DeclLoc);
+    const char *argListBegin, *argListEnd;
+    GetExtentOfArgList(startBuf, argListBegin, argListEnd);
+    while (argListBegin < argListEnd) {
+      if (*argListBegin == '^') {
+        SourceLocation CaretLoc = DeclLoc.getFileLocWithOffset(argListBegin-startBuf);
+        ReplaceText(CaretLoc, 1, "*", 1);
+      }
+      argListBegin++;
+    }
+  }
+  return;
+}
+
+void RewriteBlocks::CollectBlockDeclRefInfo(BlockExpr *Exp) {  
+  // Add initializers for any closure decl refs.
+  GetBlockDeclRefExprs(Exp->getBody());
+  if (BlockDeclRefs.size()) {
+    // Unique all "by copy" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (!BlockDeclRefs[i]->isByRef())
+        BlockByCopyDecls.insert(BlockDeclRefs[i]->getDecl());
+    // Unique all "by ref" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->isByRef()) {
+        BlockByRefDecls.insert(BlockDeclRefs[i]->getDecl());
+      }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (isBlockPointerType(BlockDeclRefs[i]->getType())) {
+        GetBlockCallExprs(Blocks[i]);
+        ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
+      }
+  }
+}
+
+std::string RewriteBlocks::SynthesizeBlockInitExpr(BlockExpr *Exp, VarDecl *VD) {
+  Blocks.push_back(Exp);
+
+  CollectBlockDeclRefInfo(Exp);
+  std::string FuncName;
+  
+  if (CurFunctionDef)
+    FuncName = std::string(CurFunctionDef->getNameAsString());
+  else if (CurMethodDef) {
+    FuncName = CurMethodDef->getSelector().getAsString();
+    // Convert colons to underscores.
+    std::string::size_type loc = 0;
+    while ((loc = FuncName.find(":", loc)) != std::string::npos)
+      FuncName.replace(loc, 1, "_");
+  } else if (VD)
+    FuncName = std::string(VD->getNameAsString());
+    
+  std::string BlockNumber = utostr(Blocks.size()-1);
+  
+  std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber;
+  std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
+  
+  std::string FunkTypeStr;
+  
+  // Get a pointer to the function type so we can cast appropriately.
+  Context->getPointerType(QualType(Exp->getFunctionType(),0)).getAsStringInternal(FunkTypeStr);
+  
+  // Rewrite the closure block with a compound literal. The first cast is
+  // to prevent warnings from the C compiler.
+  std::string Init = "(" + FunkTypeStr;
+  
+  Init += ")&" + Tag;
+  
+  // Initialize the block function.
+  Init += "((void*)" + Func;
+  
+  if (ImportedBlockDecls.size()) {
+    std::string Buf = "__" + FuncName + "_block_copy_" + BlockNumber;
+    Init += ",(void*)" + Buf;
+    Buf = "__" + FuncName + "_block_dispose_" + BlockNumber;
+    Init += ",(void*)" + Buf;
+  }
+  // Add initializers for any closure decl refs.
+  if (BlockDeclRefs.size()) {
+    // Output all "by copy" declarations.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      Init += ",";
+      if (isObjCType((*I)->getType())) {
+        Init += "[[";
+        Init += (*I)->getNameAsString();
+        Init += " retain] autorelease]";
+      } else if (isBlockPointerType((*I)->getType())) {
+        Init += "(void *)";
+        Init += (*I)->getNameAsString();
+      } else {
+        Init += (*I)->getNameAsString();
+      }
+    }
+    // Output all "by ref" declarations.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      Init += ",&";
+      Init += (*I)->getNameAsString();
+    }
+  }
+  Init += ")";
+  BlockDeclRefs.clear();
+  BlockByRefDecls.clear();
+  BlockByCopyDecls.clear();
+  ImportedBlockDecls.clear();
+
+  return Init;
+}
+
+//===----------------------------------------------------------------------===//
+// Function Body / Expression rewriting
+//===----------------------------------------------------------------------===//
+
+Stmt *RewriteBlocks::RewriteFunctionBody(Stmt *S) {
+  // Start by rewriting all children.
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
+        Stmt *newStmt = RewriteFunctionBody(CBE->getBody());
+        if (newStmt) 
+          *CI = newStmt;
+          
+        // We've just rewritten the block body in place.
+        // Now we snarf the rewritten text and stash it away for later use.
+        std::string S = Rewrite.getRewritenText(CBE->getSourceRange());
+        RewrittenBlockExprs[CBE] = S;
+        std::string Init = SynthesizeBlockInitExpr(CBE);
+        // Do the rewrite, using S.size() which contains the rewritten size.
+        ReplaceText(CBE->getLocStart(), S.size(), Init.c_str(), Init.size());
+      } else {
+        Stmt *newStmt = RewriteFunctionBody(*CI);
+        if (newStmt) 
+          *CI = newStmt;
+      }
+    }
+  // Handle specific things.
+  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
+    if (CE->getCallee()->getType()->isBlockPointerType())
+      RewriteBlockCall(CE);
+  }
+  if (CastExpr *CE = dyn_cast<CastExpr>(S)) {
+    RewriteCastExpr(CE);
+  }
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
+    for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
+         DI != DE; ++DI) {
+      
+      Decl *SD = *DI;
+      if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
+        if (isBlockPointerType(ND->getType()))
+          RewriteBlockPointerDecl(ND);
+        else if (ND->getType()->isFunctionPointerType()) 
+          CheckFunctionPointerDecl(ND->getType(), ND);
+      }
+      if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
+        if (isBlockPointerType(TD->getUnderlyingType()))
+          RewriteBlockPointerDecl(TD);
+        else if (TD->getUnderlyingType()->isFunctionPointerType()) 
+          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+      }
+    }
+  }
+  // Handle specific things.
+  if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
+    if (BDRE->isByRef())
+      RewriteBlockDeclRefExpr(BDRE);
+  }
+  // Return this stmt unmodified.
+  return S;
+}
+
+void RewriteBlocks::RewriteFunctionProtoType(QualType funcType, NamedDecl *D) {    
+  if (FunctionProtoType *fproto = dyn_cast<FunctionProtoType>(funcType)) {
+    for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(), 
+         E = fproto->arg_type_end(); I && (I != E); ++I)
+      if (isBlockPointerType(*I)) {
+        // All the args are checked/rewritten. Don't call twice!
+        RewriteBlockPointerDecl(D);
+        break;
+      }
+  }
+}
+
+void RewriteBlocks::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
+  const PointerType *PT = funcType->getAsPointerType();
+  if (PT && PointerTypeTakesAnyBlockArguments(funcType))
+    RewriteFunctionProtoType(PT->getPointeeType(), ND);
+}
+
+/// HandleDeclInMainFile - This is called for each top-level decl defined in the
+/// main file of the input.
+void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // Since function prototypes don't have ParmDecl's, we check the function
+    // prototype. This enables us to rewrite function declarations and
+    // definitions using the same code.
+    RewriteFunctionProtoType(FD->getType(), FD);
+
+    // FIXME: Handle CXXTryStmt
+    if (CompoundStmt *Body = FD->getCompoundBody(*Context)) {
+      CurFunctionDef = FD;
+      FD->setBody(cast_or_null<CompoundStmt>(RewriteFunctionBody(Body)));
+      // This synthesizes and inserts the block "impl" struct, invoke function,
+      // and any copy/dispose helper functions.
+      InsertBlockLiteralsWithinFunction(FD);
+      CurFunctionDef = 0;
+    } 
+    return;
+  }
+  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    RewriteMethodDecl(MD);
+    if (Stmt *Body = MD->getBody(*Context)) {
+      CurMethodDef = MD;
+      RewriteFunctionBody(Body);
+      InsertBlockLiteralsWithinMethod(MD);
+      CurMethodDef = 0;
+    }
+  }
+  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (isBlockPointerType(VD->getType())) {
+      RewriteBlockPointerDecl(VD);
+      if (VD->getInit()) {
+        if (BlockExpr *CBE = dyn_cast<BlockExpr>(VD->getInit())) {
+          RewriteFunctionBody(CBE->getBody(*Context));
+
+          // We've just rewritten the block body in place.
+          // Now we snarf the rewritten text and stash it away for later use.
+          std::string S = Rewrite.getRewritenText(CBE->getSourceRange());
+          RewrittenBlockExprs[CBE] = S;
+          std::string Init = SynthesizeBlockInitExpr(CBE, VD);
+          // Do the rewrite, using S.size() which contains the rewritten size.
+          ReplaceText(CBE->getLocStart(), S.size(), Init.c_str(), Init.size());
+          SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), 
+                                  VD->getNameAsCString());
+        } else if (CastExpr *CE = dyn_cast<CastExpr>(VD->getInit())) {
+          RewriteCastExpr(CE);
+        }
+      }
+    } else if (VD->getType()->isFunctionPointerType()) {
+      CheckFunctionPointerDecl(VD->getType(), VD);
+      if (VD->getInit()) {
+        if (CastExpr *CE = dyn_cast<CastExpr>(VD->getInit())) {
+          RewriteCastExpr(CE);
+        }
+      }
+    }
+    return;
+  }
+  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+    if (isBlockPointerType(TD->getUnderlyingType()))
+      RewriteBlockPointerDecl(TD);
+    else if (TD->getUnderlyingType()->isFunctionPointerType()) 
+      CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+    return;
+  }
+  if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
+    if (RD->isDefinition()) {
+      for (RecordDecl::field_iterator i = RD->field_begin(*Context), 
+             e = RD->field_end(*Context); i != e; ++i) {
+        FieldDecl *FD = *i;
+        if (isBlockPointerType(FD->getType()))
+          RewriteBlockPointerDecl(FD);
+      }
+    }
+    return;
+  }
+}
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
new file mode 100644
index 0000000..86f3037
--- /dev/null
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -0,0 +1,4691 @@
+//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Hacks and fun related to the code rewriter.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+using namespace clang;
+using llvm::utostr;
+
+namespace {
+  class RewriteObjC : public ASTConsumer {
+    Rewriter Rewrite;
+    Diagnostic &Diags;
+    const LangOptions &LangOpts;
+    unsigned RewriteFailedDiag;
+    unsigned TryFinallyContainsReturnDiag;
+        
+    ASTContext *Context;
+    SourceManager *SM;
+    TranslationUnitDecl *TUDecl;
+    FileID MainFileID;
+    const char *MainFileStart, *MainFileEnd;
+    SourceLocation LastIncLoc;
+    
+    llvm::SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
+    llvm::SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
+    llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls;
+    llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
+    llvm::SmallVector<Stmt *, 32> Stmts;
+    llvm::SmallVector<int, 8> ObjCBcLabelNo;
+    // Remember all the @protocol(<expr>) expressions.
+    llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
+    
+    unsigned NumObjCStringLiterals;
+    
+    FunctionDecl *MsgSendFunctionDecl;
+    FunctionDecl *MsgSendSuperFunctionDecl;
+    FunctionDecl *MsgSendStretFunctionDecl;
+    FunctionDecl *MsgSendSuperStretFunctionDecl;
+    FunctionDecl *MsgSendFpretFunctionDecl;
+    FunctionDecl *GetClassFunctionDecl;
+    FunctionDecl *GetMetaClassFunctionDecl;
+    FunctionDecl *SelGetUidFunctionDecl;
+    FunctionDecl *CFStringFunctionDecl;
+    FunctionDecl *SuperContructorFunctionDecl;
+      
+    // ObjC string constant support.
+    VarDecl *ConstantStringClassReference;
+    RecordDecl *NSStringRecord;
+    
+    // ObjC foreach break/continue generation support.
+    int BcLabelCount;
+    
+    // Needed for super.
+    ObjCMethodDecl *CurMethodDef;
+    RecordDecl *SuperStructDecl;
+    RecordDecl *ConstantStringDecl;
+    
+    TypeDecl *ProtocolTypeDecl;
+    QualType getProtocolType();
+    
+    // Needed for header files being rewritten
+    bool IsHeader;
+    
+    std::string InFileName;
+    llvm::raw_ostream* OutFile;
+
+    bool SilenceRewriteMacroWarning;
+
+    std::string Preamble;
+
+    // Block expressions.
+    llvm::SmallVector<BlockExpr *, 32> Blocks;
+    llvm::SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs;
+    llvm::DenseMap<BlockDeclRefExpr *, CallExpr *> BlockCallExprs;
+    
+    // Block related declarations.
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
+
+    llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
+
+    // This maps a property to it's assignment statement.
+    llvm::DenseMap<ObjCPropertyRefExpr *, BinaryOperator *> PropSetters;
+    // This maps a property to it's synthesied message expression.
+    // This allows us to rewrite chained getters (e.g. o.a.b.c).
+    llvm::DenseMap<ObjCPropertyRefExpr *, Stmt *> PropGetters;
+    
+    // This maps an original source AST to it's rewritten form. This allows
+    // us to avoid rewriting the same node twice (which is very uncommon).
+    // This is needed to support some of the exotic property rewriting.
+    llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
+
+    FunctionDecl *CurFunctionDef;
+    VarDecl *GlobalVarDecl;
+    
+    bool DisableReplaceStmt;
+    
+    static const int OBJC_ABI_VERSION =7 ;
+  public:
+    virtual void Initialize(ASTContext &context);
+
+    // Top Level Driver code.
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+        HandleTopLevelSingleDecl(*I);
+    }
+    void HandleTopLevelSingleDecl(Decl *D);
+    void HandleDeclInMainFile(Decl *D);
+    RewriteObjC(std::string inFile, llvm::raw_ostream *OS,
+                Diagnostic &D, const LangOptions &LOpts,
+                bool silenceMacroWarn);
+
+    ~RewriteObjC() {}
+    
+    virtual void HandleTranslationUnit(ASTContext &C);
+    
+    void ReplaceStmt(Stmt *Old, Stmt *New) {
+      Stmt *ReplacingStmt = ReplacedNodes[Old];
+  
+      if (ReplacingStmt)
+        return; // We can't rewrite the same node twice.
+
+      if (DisableReplaceStmt)
+        return; // Used when rewriting the assignment of a property setter.
+
+      // If replacement succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceStmt(Old, New)) {
+        ReplacedNodes[Old] = New;
+        return;
+      }
+      if (SilenceRewriteMacroWarning)
+        return;
+      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                   << Old->getSourceRange();
+    }
+
+    void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
+      // Measaure the old text.
+      int Size = Rewrite.getRangeSize(SrcRange);
+      if (Size == -1) {
+        Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                     << Old->getSourceRange();
+        return;
+      }
+      // Get the new text.
+      std::string SStr;
+      llvm::raw_string_ostream S(SStr);
+      New->printPretty(S);
+      const std::string &Str = S.str();
+
+      // If replacement succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, &Str[0], Str.size())) {
+        ReplacedNodes[Old] = New;
+        return;
+      }
+      if (SilenceRewriteMacroWarning)
+        return;
+      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                   << Old->getSourceRange();
+    }
+
+    void InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen,
+                    bool InsertAfter = true) {
+      // If insertion succeeded or warning disabled return with no warning.
+      if (!Rewrite.InsertText(Loc, StrData, StrLen, InsertAfter) ||
+          SilenceRewriteMacroWarning)
+        return;
+      
+      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
+    }
+    
+    void RemoveText(SourceLocation Loc, unsigned StrLen) {
+      // If removal succeeded or warning disabled return with no warning.
+      if (!Rewrite.RemoveText(Loc, StrLen) || SilenceRewriteMacroWarning)
+        return;
+      
+      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
+    }
+
+    void ReplaceText(SourceLocation Start, unsigned OrigLength,
+                     const char *NewStr, unsigned NewLength) {
+      // If removal succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(Start, OrigLength, NewStr, NewLength) ||
+          SilenceRewriteMacroWarning)
+        return;
+      
+      Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
+    }
+    
+    // Syntactic Rewriting.
+    void RewritePrologue(SourceLocation Loc);
+    void RewriteInclude();
+    void RewriteTabs();
+    void RewriteForwardClassDecl(ObjCClassDecl *Dcl);
+    void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                 ObjCImplementationDecl *IMD,
+                                 ObjCCategoryImplDecl *CID);
+    void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
+    void RewriteImplementationDecl(Decl *Dcl);
+    void RewriteObjCMethodDecl(ObjCMethodDecl *MDecl, std::string &ResultStr);
+    void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
+    void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
+    void RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *Dcl);
+    void RewriteMethodDeclaration(ObjCMethodDecl *Method);
+    void RewriteProperty(ObjCPropertyDecl *prop);
+    void RewriteFunctionDecl(FunctionDecl *FD);
+    void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
+    void RewriteObjCQualifiedInterfaceTypes(Expr *E);
+    bool needToScanForQualifiers(QualType T);
+    ObjCInterfaceDecl *isSuperReceiver(Expr *recExpr);
+    QualType getSuperStructType();
+    QualType getConstantStringStructType();
+    bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
+    
+    // Expression Rewriting.
+    Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
+    void CollectPropertySetters(Stmt *S);
+    
+    Stmt *CurrentBody;
+    ParentMap *PropParentMap; // created lazily.
+    
+    Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
+    Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation OrigStart);
+    Stmt *RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr);
+    Stmt *RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt, 
+                                SourceRange SrcRange);
+    Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
+    Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
+    Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
+    Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
+    void WarnAboutReturnGotoContinueOrBreakStmts(Stmt *S);
+    Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
+    Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
+    Stmt *RewriteObjCCatchStmt(ObjCAtCatchStmt *S);
+    Stmt *RewriteObjCFinallyStmt(ObjCAtFinallyStmt *S);
+    Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
+    Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                       SourceLocation OrigEnd);
+    CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD, 
+                                           Expr **args, unsigned nargs);
+    Stmt *SynthMessageExpr(ObjCMessageExpr *Exp);
+    Stmt *RewriteBreakStmt(BreakStmt *S);
+    Stmt *RewriteContinueStmt(ContinueStmt *S);
+    void SynthCountByEnumWithState(std::string &buf);
+    
+    void SynthMsgSendFunctionDecl();
+    void SynthMsgSendSuperFunctionDecl();
+    void SynthMsgSendStretFunctionDecl();
+    void SynthMsgSendFpretFunctionDecl();
+    void SynthMsgSendSuperStretFunctionDecl();
+    void SynthGetClassFunctionDecl();
+    void SynthGetMetaClassFunctionDecl();
+    void SynthSelGetUidFunctionDecl();
+    void SynthSuperContructorFunctionDecl();
+      
+    // Metadata emission.
+    void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                  std::string &Result);
+    
+    void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
+                                     std::string &Result);
+    
+    template<typename MethodIterator>
+    void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                    MethodIterator MethodEnd,
+                                    bool IsInstanceMethod,
+                                    const char *prefix,
+                                    const char *ClassName,
+                                    std::string &Result);
+    
+    void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
+                                     const char *prefix,
+                                     const char *ClassName,
+                                     std::string &Result);
+    void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots,
+                                         const char *prefix, 
+                                         const char *ClassName,
+                                         std::string &Result);
+    void SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                      std::string &Result);
+    void SynthesizeIvarOffsetComputation(ObjCImplementationDecl *IDecl, 
+                                         ObjCIvarDecl *ivar, 
+                                         std::string &Result);
+    void RewriteImplementations();
+    void SynthesizeMetaDataIntoBuffer(std::string &Result);
+    
+    // Block rewriting.
+    void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);  
+    void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
+    
+    void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
+    void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
+    
+    // Block specific rewrite rules.    
+    void RewriteBlockCall(CallExpr *Exp);
+    void RewriteBlockPointerDecl(NamedDecl *VD);
+    Stmt *RewriteBlockDeclRefExpr(BlockDeclRefExpr *VD);
+    void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
+    
+    std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 
+                                      const char *funcName, std::string Tag);
+    std::string SynthesizeBlockFunc(BlockExpr *CE, int i, 
+                                      const char *funcName, std::string Tag);
+    std::string SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
+                                    bool hasCopyDisposeHelpers);
+    Stmt *SynthesizeBlockCall(CallExpr *Exp);
+    void SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                   const char *FunName);
+    
+    void CollectBlockDeclRefInfo(BlockExpr *Exp);
+    void GetBlockCallExprs(Stmt *S);
+    void GetBlockDeclRefExprs(Stmt *S);
+    
+    // We avoid calling Type::isBlockPointerType(), since it operates on the
+    // canonical type. We only care if the top-level type is a closure pointer.
+    bool isTopLevelBlockPointerType(QualType T) {
+      return isa<BlockPointerType>(T);
+    }
+    
+    // FIXME: This predicate seems like it would be useful to add to ASTContext.
+    bool isObjCType(QualType T) {
+      if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
+        return false;
+        
+      QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
+      
+      if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
+          OCT == Context->getCanonicalType(Context->getObjCClassType()))
+        return true;
+        
+      if (const PointerType *PT = OCT->getAsPointerType()) {
+        if (isa<ObjCInterfaceType>(PT->getPointeeType()) || 
+            isa<ObjCQualifiedIdType>(PT->getPointeeType()))
+          return true;
+      }
+      return false;
+    }
+    bool PointerTypeTakesAnyBlockArguments(QualType QT);
+    void GetExtentOfArgList(const char *Name, const char *&LParen,
+                            const char *&RParen);
+    void RewriteCastExpr(CStyleCastExpr *CE);
+    
+    FunctionDecl *SynthBlockInitFunctionDecl(const char *name);
+    Stmt *SynthBlockInitExpr(BlockExpr *Exp);
+    
+    void QuoteDoublequotes(std::string &From, std::string &To) {
+      for(unsigned i = 0; i < From.length(); i++) {
+        if (From[i] == '"')
+          To += "\\\"";
+        else
+          To += From[i];
+      }
+    }
+  };
+}
+
+void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType, 
+                                                   NamedDecl *D) {    
+  if (FunctionProtoType *fproto = dyn_cast<FunctionProtoType>(funcType)) {
+    for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(), 
+         E = fproto->arg_type_end(); I && (I != E); ++I)
+      if (isTopLevelBlockPointerType(*I)) {
+        // All the args are checked/rewritten. Don't call twice!
+        RewriteBlockPointerDecl(D);
+        break;
+      }
+  }
+}
+
+void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
+  const PointerType *PT = funcType->getAsPointerType();
+  if (PT && PointerTypeTakesAnyBlockArguments(funcType))
+    RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
+}
+
+static bool IsHeaderFile(const std::string &Filename) {
+  std::string::size_type DotPos = Filename.rfind('.');
+  
+  if (DotPos == std::string::npos) {
+    // no file extension
+    return false; 
+  }
+  
+  std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
+  // C header: .h
+  // C++ header: .hh or .H;
+  return Ext == "h" || Ext == "hh" || Ext == "H";
+}    
+
+RewriteObjC::RewriteObjC(std::string inFile, llvm::raw_ostream* OS,
+                         Diagnostic &D, const LangOptions &LOpts,
+                         bool silenceMacroWarn)
+      : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
+        SilenceRewriteMacroWarning(silenceMacroWarn) {
+  IsHeader = IsHeaderFile(inFile);
+  RewriteFailedDiag = Diags.getCustomDiagID(Diagnostic::Warning, 
+               "rewriting sub-expression within a macro (may not be correct)");
+  TryFinallyContainsReturnDiag = Diags.getCustomDiagID(Diagnostic::Warning, 
+               "rewriter doesn't support user-specified control flow semantics "
+               "for @try/@finally (code may not execute properly)");
+}
+
+ASTConsumer *clang::CreateObjCRewriter(const std::string& InFile,
+                                       llvm::raw_ostream* OS,
+                                       Diagnostic &Diags, 
+                                       const LangOptions &LOpts,
+                                       bool SilenceRewriteMacroWarning) {
+  return new RewriteObjC(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning);
+}
+
+void RewriteObjC::Initialize(ASTContext &context) {
+  Context = &context;
+  SM = &Context->getSourceManager();
+  TUDecl = Context->getTranslationUnitDecl();
+  MsgSendFunctionDecl = 0;
+  MsgSendSuperFunctionDecl = 0;
+  MsgSendStretFunctionDecl = 0;
+  MsgSendSuperStretFunctionDecl = 0;
+  MsgSendFpretFunctionDecl = 0;
+  GetClassFunctionDecl = 0;
+  GetMetaClassFunctionDecl = 0;
+  SelGetUidFunctionDecl = 0;
+  CFStringFunctionDecl = 0;
+  ConstantStringClassReference = 0;
+  NSStringRecord = 0;
+  CurMethodDef = 0;
+  CurFunctionDef = 0;
+  GlobalVarDecl = 0;
+  SuperStructDecl = 0;
+  ProtocolTypeDecl = 0;
+  ConstantStringDecl = 0;
+  BcLabelCount = 0;
+  SuperContructorFunctionDecl = 0;
+  NumObjCStringLiterals = 0;
+  PropParentMap = 0;
+  CurrentBody = 0;
+  DisableReplaceStmt = false;
+  
+  // Get the ID and start/end of the main file.
+  MainFileID = SM->getMainFileID();
+  const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
+  MainFileStart = MainBuf->getBufferStart();
+  MainFileEnd = MainBuf->getBufferEnd();
+     
+  Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOptions());
+  
+  // declaring objc_selector outside the parameter list removes a silly
+  // scope related warning...
+  if (IsHeader)
+    Preamble = "#pragma once\n";
+  Preamble += "struct objc_selector; struct objc_class;\n";
+  Preamble += "struct __rw_objc_super { struct objc_object *object; ";
+  Preamble += "struct objc_object *superClass; ";
+  if (LangOpts.Microsoft) {
+    // Add a constructor for creating temporary objects.
+    Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) "
+                ": ";
+    Preamble += "object(o), superClass(s) {} ";
+  }
+  Preamble += "};\n";
+  Preamble += "#ifndef _REWRITER_typedef_Protocol\n";
+  Preamble += "typedef struct objc_object Protocol;\n";
+  Preamble += "#define _REWRITER_typedef_Protocol\n";
+  Preamble += "#endif\n";
+  if (LangOpts.Microsoft) {
+    Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
+    Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
+  } else
+    Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper";
+  Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend_stret";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper_stret";
+  Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match";
+  Preamble += "(struct objc_class *, struct objc_object *);\n";
+  // @synchronized hooks.
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_enter(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_exit(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
+  Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
+  Preamble += "struct __objcFastEnumerationState {\n\t";
+  Preamble += "unsigned long state;\n\t";
+  Preamble += "void **itemsPtr;\n\t";
+  Preamble += "unsigned long *mutationsPtr;\n\t";
+  Preamble += "unsigned long extra[5];\n};\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
+  Preamble += "#define __FASTENUMERATIONSTATE\n";
+  Preamble += "#endif\n";
+  Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "struct __NSConstantStringImpl {\n";
+  Preamble += "  int *isa;\n";
+  Preamble += "  int flags;\n";
+  Preamble += "  char *str;\n";
+  Preamble += "  long length;\n";
+  Preamble += "};\n";
+  Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n";
+  Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
+  Preamble += "#else\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
+  Preamble += "#endif\n";
+  Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "#endif\n";
+  // Blocks preamble.
+  Preamble += "#ifndef BLOCK_IMPL\n";
+  Preamble += "#define BLOCK_IMPL\n";
+  Preamble += "struct __block_impl {\n";
+  Preamble += "  void *isa;\n";
+  Preamble += "  int Flags;\n";
+  Preamble += "  int Size;\n";
+  Preamble += "  void *FuncPtr;\n";
+  Preamble += "};\n";
+  Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
+  Preamble += "__OBJC_RW_STATICIMPORT void _Block_object_assign(void *, const void *, const int);\n";
+  Preamble += "__OBJC_RW_STATICIMPORT void _Block_object_dispose(const void *, const int);\n";
+  Preamble += "__OBJC_RW_STATICIMPORT void *_NSConcreteGlobalBlock[32];\n";
+  Preamble += "__OBJC_RW_STATICIMPORT void *_NSConcreteStackBlock[32];\n";
+  Preamble += "#endif\n";
+  if (LangOpts.Microsoft) {
+    Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
+    Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
+    Preamble += "#define __attribute__(X)\n";
+  }
+}
+
+
+//===----------------------------------------------------------------------===//
+// Top Level Driver Code
+//===----------------------------------------------------------------------===//
+
+void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
+  // Two cases: either the decl could be in the main file, or it could be in a
+  // #included file.  If the former, rewrite it now.  If the later, check to see
+  // if we rewrote the #include/#import.
+  SourceLocation Loc = D->getLocation();
+  Loc = SM->getInstantiationLoc(Loc);
+  
+  // 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<FunctionDecl>(D)) {
+    RewriteFunctionDecl(FD);
+  } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
+    // declared in <Foundation/NSString.h>
+    if (strcmp(FVD->getNameAsCString(), "_NSConstantStringClassReference") == 0) {
+      ConstantStringClassReference = FVD;
+      return;
+    }
+  } else if (ObjCInterfaceDecl *MD = dyn_cast<ObjCInterfaceDecl>(D)) {
+    RewriteInterfaceDecl(MD);
+  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
+    RewriteCategoryDecl(CD);
+  } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+    RewriteProtocolDecl(PD);
+  } else if (ObjCForwardProtocolDecl *FP = 
+             dyn_cast<ObjCForwardProtocolDecl>(D)){
+    RewriteForwardProtocolDecl(FP);
+  } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
+    // Recurse into linkage specifications
+    for (DeclContext::decl_iterator DI = LSD->decls_begin(*Context),
+                                 DIEnd = LSD->decls_end(*Context);
+         DI != DIEnd; ++DI)
+      HandleTopLevelSingleDecl(*DI);
+  }
+  // If we have a decl in the main file, see if we should rewrite it.
+  if (SM->isFromMainFile(Loc))
+    return HandleDeclInMainFile(D);
+}
+
+//===----------------------------------------------------------------------===//
+// Syntactic (non-AST) Rewriting Code
+//===----------------------------------------------------------------------===//
+
+void RewriteObjC::RewriteInclude() {
+  SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
+  std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
+  const char *MainBufStart = MainBuf.first;
+  const char *MainBufEnd = MainBuf.second;
+  size_t ImportLen = strlen("import");
+  size_t IncludeLen = strlen("include");
+                             
+  // Loop over the whole file, looking for includes.
+  for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
+    if (*BufPtr == '#') {
+      if (++BufPtr == MainBufEnd)
+        return;
+      while (*BufPtr == ' ' || *BufPtr == '\t')
+        if (++BufPtr == MainBufEnd)
+          return;
+      if (!strncmp(BufPtr, "import", ImportLen)) {
+        // replace import with include
+        SourceLocation ImportLoc = 
+          LocStart.getFileLocWithOffset(BufPtr-MainBufStart);
+        ReplaceText(ImportLoc, ImportLen, "include", IncludeLen);
+        BufPtr += ImportLen;
+      }
+    }
+  }
+}
+
+void RewriteObjC::RewriteTabs() {
+  std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
+  const char *MainBufStart = MainBuf.first;
+  const char *MainBufEnd = MainBuf.second;
+  
+  // Loop over the whole file, looking for tabs.
+  for (const char *BufPtr = MainBufStart; BufPtr != MainBufEnd; ++BufPtr) {
+    if (*BufPtr != '\t')
+      continue;
+    
+    // Okay, we found a tab.  This tab will turn into at least one character,
+    // but it depends on which 'virtual column' it is in.  Compute that now.
+    unsigned VCol = 0;
+    while (BufPtr-VCol != MainBufStart && BufPtr[-VCol-1] != '\t' &&
+           BufPtr[-VCol-1] != '\n' && BufPtr[-VCol-1] != '\r')
+      ++VCol;
+    
+    // Okay, now that we know the virtual column, we know how many spaces to
+    // insert.  We assume 8-character tab-stops.
+    unsigned Spaces = 8-(VCol & 7);
+    
+    // Get the location of the tab.
+    SourceLocation TabLoc = SM->getLocForStartOfFile(MainFileID);
+    TabLoc = TabLoc.getFileLocWithOffset(BufPtr-MainBufStart);
+    
+    // Rewrite the single tab character into a sequence of spaces.
+    ReplaceText(TabLoc, 1, "        ", Spaces);
+  }
+}
+
+static std::string getIvarAccessString(ObjCInterfaceDecl *ClassDecl,
+                                       ObjCIvarDecl *OID) {
+  std::string S;
+  S = "((struct ";
+  S += ClassDecl->getIdentifier()->getName();
+  S += "_IMPL *)self)->";
+  S += OID->getNameAsCString();
+  return S;
+}
+
+void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                          ObjCImplementationDecl *IMD,
+                                          ObjCCategoryImplDecl *CID) {
+  SourceLocation startLoc = PID->getLocStart();
+  InsertText(startLoc, "// ", 3);
+  const char *startBuf = SM->getCharacterData(startLoc);
+  assert((*startBuf == '@') && "bogus @synthesize location");
+  const char *semiBuf = strchr(startBuf, ';');
+  assert((*semiBuf == ';') && "@synthesize: can't find ';'");
+  SourceLocation onePastSemiLoc =
+    startLoc.getFileLocWithOffset(semiBuf-startBuf+1);
+
+  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+    return; // FIXME: is this correct?
+    
+  // Generate the 'getter' function.
+  ObjCPropertyDecl *PD = PID->getPropertyDecl();
+  ObjCInterfaceDecl *ClassDecl = PD->getGetterMethodDecl()->getClassInterface();
+  ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
+  
+  if (!OID)
+    return;
+    
+  std::string Getr;
+  RewriteObjCMethodDecl(PD->getGetterMethodDecl(), Getr);
+  Getr += "{ ";
+  // Synthesize an explicit cast to gain access to the ivar.
+  // FIXME: deal with code generation implications for various property 
+  // attributes (copy, retain, nonatomic). 
+  // See objc-act.c:objc_synthesize_new_getter() for details.
+  Getr += "return " + getIvarAccessString(ClassDecl, OID);
+  Getr += "; }";
+  InsertText(onePastSemiLoc, Getr.c_str(), Getr.size());
+  if (PD->isReadOnly())
+    return;
+    
+  // Generate the 'setter' function.
+  std::string Setr;
+  RewriteObjCMethodDecl(PD->getSetterMethodDecl(), Setr);
+  Setr += "{ ";
+  // Synthesize an explicit cast to initialize the ivar.
+  // FIXME: deal with code generation implications for various property 
+  // attributes (copy, retain, nonatomic). 
+  // See objc-act.c:objc_synthesize_new_setter() for details.
+  Setr += getIvarAccessString(ClassDecl, OID) + " = ";
+  Setr += PD->getNameAsCString();
+  Setr += "; }";
+  InsertText(onePastSemiLoc, Setr.c_str(), Setr.size());
+}
+
+void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = ClassDecl->getLocation();
+  const char *startBuf = SM->getCharacterData(startLoc);
+  const char *semiPtr = strchr(startBuf, ';');
+  
+  // Translate to typedef's that forward reference structs with the same name
+  // as the class. As a convenience, we include the original declaration
+  // as a comment.
+  std::string typedefString;
+  typedefString += "// ";
+  typedefString.append(startBuf, semiPtr-startBuf+1);
+  typedefString += "\n";
+  for (ObjCClassDecl::iterator I = ClassDecl->begin(), E = ClassDecl->end();
+       I != E; ++I) {
+    ObjCInterfaceDecl *ForwardDecl = *I;
+    typedefString += "#ifndef _REWRITER_typedef_";
+    typedefString += ForwardDecl->getNameAsString();
+    typedefString += "\n";
+    typedefString += "#define _REWRITER_typedef_";
+    typedefString += ForwardDecl->getNameAsString();
+    typedefString += "\n";
+    typedefString += "typedef struct objc_object ";
+    typedefString += ForwardDecl->getNameAsString();
+    typedefString += ";\n#endif\n";
+  }
+  
+  // Replace the @class with typedefs corresponding to the classes.
+  ReplaceText(startLoc, semiPtr-startBuf+1, 
+              typedefString.c_str(), typedefString.size());
+}
+
+void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
+  SourceLocation LocStart = Method->getLocStart();
+  SourceLocation LocEnd = Method->getLocEnd();
+    
+  if (SM->getInstantiationLineNumber(LocEnd) >
+      SM->getInstantiationLineNumber(LocStart)) {
+    InsertText(LocStart, "#if 0\n", 6);
+    ReplaceText(LocEnd, 1, ";\n#endif\n", 9);
+  } else {
+    InsertText(LocStart, "// ", 3);
+  }
+}
+
+void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) 
+{
+  SourceLocation Loc = prop->getLocation();
+  
+  ReplaceText(Loc, 0, "// ", 3);
+  
+  // FIXME: handle properties that are declared across multiple lines.
+}
+
+void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
+  SourceLocation LocStart = CatDecl->getLocStart();
+  
+  // FIXME: handle category headers that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ", 3);
+  
+  for (ObjCCategoryDecl::instmeth_iterator 
+         I = CatDecl->instmeth_begin(*Context), 
+         E = CatDecl->instmeth_end(*Context); 
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+  for (ObjCCategoryDecl::classmeth_iterator 
+         I = CatDecl->classmeth_begin(*Context), 
+         E = CatDecl->classmeth_end(*Context);
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+
+  // Lastly, comment out the @end.
+  ReplaceText(CatDecl->getAtEndLoc(), 0, "// ", 3);
+}
+
+void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
+  std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
+  
+  SourceLocation LocStart = PDecl->getLocStart();
+  
+  // FIXME: handle protocol headers that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ", 3);
+  
+  for (ObjCProtocolDecl::instmeth_iterator 
+         I = PDecl->instmeth_begin(*Context), 
+         E = PDecl->instmeth_end(*Context); 
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+  for (ObjCProtocolDecl::classmeth_iterator
+         I = PDecl->classmeth_begin(*Context), 
+         E = PDecl->classmeth_end(*Context);
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+
+  // Lastly, comment out the @end.
+  SourceLocation LocEnd = PDecl->getAtEndLoc();
+  ReplaceText(LocEnd, 0, "// ", 3);
+
+  // Must comment out @optional/@required
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  for (const char *p = startBuf; p < endBuf; p++) {
+    if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
+      std::string CommentedOptional = "/* @optional */";
+      SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@optional"),
+                  CommentedOptional.c_str(), CommentedOptional.size());
+      
+    }
+    else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
+      std::string CommentedRequired = "/* @required */";
+      SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@required"),
+                  CommentedRequired.c_str(), CommentedRequired.size());
+      
+    }
+  }
+}
+
+void RewriteObjC::RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *PDecl) {
+  SourceLocation LocStart = PDecl->getLocation();
+  if (LocStart.isInvalid())
+    assert(false && "Invalid SourceLocation");
+  // FIXME: handle forward protocol that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ", 3);
+}
+
+void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD, 
+                                        std::string &ResultStr) {
+  //fprintf(stderr,"In RewriteObjCMethodDecl\n");
+  const FunctionType *FPRetType = 0;
+  ResultStr += "\nstatic ";
+  if (OMD->getResultType()->isObjCQualifiedIdType())
+    ResultStr += "id";
+  else if (OMD->getResultType()->isFunctionPointerType() ||
+           OMD->getResultType()->isBlockPointerType()) {
+    // needs special handling, since pointer-to-functions have special
+    // syntax (where a decaration models use).
+    QualType retType = OMD->getResultType();
+    QualType PointeeTy;
+    if (const PointerType* PT = retType->getAsPointerType())
+      PointeeTy = PT->getPointeeType();
+    else if (const BlockPointerType *BPT = retType->getAsBlockPointerType())
+      PointeeTy = BPT->getPointeeType();
+    if ((FPRetType = PointeeTy->getAsFunctionType())) {
+      ResultStr += FPRetType->getResultType().getAsString();
+      ResultStr += "(*";
+    }
+  } else
+    ResultStr += OMD->getResultType().getAsString();
+  ResultStr += " ";
+  
+  // Unique method name
+  std::string NameStr;
+  
+  if (OMD->isInstanceMethod())
+    NameStr += "_I_";
+  else
+    NameStr += "_C_";
+  
+  NameStr += OMD->getClassInterface()->getNameAsString();
+  NameStr += "_";
+  
+  if (ObjCCategoryImplDecl *CID = 
+      dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
+    NameStr += CID->getNameAsString();
+    NameStr += "_";
+  }
+  // Append selector names, replacing ':' with '_' 
+  {
+    std::string selString = OMD->getSelector().getAsString();
+    int len = selString.size();
+    for (int i = 0; i < len; i++)
+      if (selString[i] == ':')
+        selString[i] = '_';
+    NameStr += selString;
+  }
+  // Remember this name for metadata emission
+  MethodInternalNames[OMD] = NameStr;
+  ResultStr += NameStr;
+  
+  // Rewrite arguments
+  ResultStr += "(";
+  
+  // invisible arguments
+  if (OMD->isInstanceMethod()) {
+    QualType selfTy = Context->getObjCInterfaceType(OMD->getClassInterface());
+    selfTy = Context->getPointerType(selfTy);
+    if (!LangOpts.Microsoft) {
+      if (ObjCSynthesizedStructs.count(OMD->getClassInterface()))
+        ResultStr += "struct ";
+    }
+    // When rewriting for Microsoft, explicitly omit the structure name.
+    ResultStr += OMD->getClassInterface()->getNameAsString();
+    ResultStr += " *";
+  }
+  else
+    ResultStr += Context->getObjCClassType().getAsString();
+  
+  ResultStr += " self, ";
+  ResultStr += Context->getObjCSelType().getAsString();
+  ResultStr += " _cmd";
+  
+  // Method arguments.
+  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
+       E = OMD->param_end(); PI != E; ++PI) {
+    ParmVarDecl *PDecl = *PI;
+    ResultStr += ", ";
+    if (PDecl->getType()->isObjCQualifiedIdType()) {
+      ResultStr += "id ";
+      ResultStr += PDecl->getNameAsString();
+    } else {
+      std::string Name = PDecl->getNameAsString();
+      if (isTopLevelBlockPointerType(PDecl->getType())) {
+        // Make sure we convert "t (^)(...)" to "t (*)(...)".
+        const BlockPointerType *BPT = PDecl->getType()->getAsBlockPointerType();
+        Context->getPointerType(BPT->getPointeeType()).getAsStringInternal(Name);
+      } else
+        PDecl->getType().getAsStringInternal(Name);
+      ResultStr += Name;
+    }
+  }
+  if (OMD->isVariadic())
+    ResultStr += ", ...";
+  ResultStr += ") ";
+  
+  if (FPRetType) {
+    ResultStr += ")"; // close the precedence "scope" for "*".
+    
+    // Now, emit the argument types (if any).
+    if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
+      ResultStr += "(";
+      for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
+        if (i) ResultStr += ", ";
+        std::string ParamStr = FT->getArgType(i).getAsString();
+        ResultStr += ParamStr;
+      }
+      if (FT->isVariadic()) {
+        if (FT->getNumArgs()) ResultStr += ", ";
+        ResultStr += "...";
+      }
+      ResultStr += ")";
+    } else {
+      ResultStr += "()";
+    }
+  }
+}
+void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
+  ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
+  ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
+  
+  if (IMD)
+    InsertText(IMD->getLocStart(), "// ", 3);
+  else
+    InsertText(CID->getLocStart(), "// ", 3);
+      
+  for (ObjCCategoryImplDecl::instmeth_iterator
+       I = IMD ? IMD->instmeth_begin(*Context) : CID->instmeth_begin(*Context),
+       E = IMD ? IMD->instmeth_end(*Context) : CID->instmeth_end(*Context);
+       I != E; ++I) {
+    std::string ResultStr;
+    ObjCMethodDecl *OMD = *I;
+    RewriteObjCMethodDecl(OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody(*Context)->getLocStart();
+
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf,
+                ResultStr.c_str(), ResultStr.size());
+  }
+  
+  for (ObjCCategoryImplDecl::classmeth_iterator
+       I = IMD ? IMD->classmeth_begin(*Context) : CID->classmeth_begin(*Context),
+       E = IMD ? IMD->classmeth_end(*Context) : CID->classmeth_end(*Context);
+       I != E; ++I) {
+    std::string ResultStr;
+    ObjCMethodDecl *OMD = *I;
+    RewriteObjCMethodDecl(OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody(*Context)->getLocStart();
+    
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf,
+                ResultStr.c_str(), ResultStr.size());    
+  }
+  for (ObjCCategoryImplDecl::propimpl_iterator
+       I = IMD ? IMD->propimpl_begin(*Context) : CID->propimpl_begin(*Context),
+       E = IMD ? IMD->propimpl_end(*Context) : CID->propimpl_end(*Context); 
+       I != E; ++I) {
+    RewritePropertyImplDecl(*I, IMD, CID);
+  }
+
+  if (IMD)
+    InsertText(IMD->getLocEnd(), "// ", 3);
+  else
+   InsertText(CID->getLocEnd(), "// ", 3); 
+}
+
+void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
+  std::string ResultStr;
+  if (!ObjCForwardDecls.count(ClassDecl)) {
+    // we haven't seen a forward decl - generate a typedef.
+    ResultStr = "#ifndef _REWRITER_typedef_";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += "\n";
+    ResultStr += "#define _REWRITER_typedef_";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += "\n";
+    ResultStr += "typedef struct objc_object ";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += ";\n#endif\n";
+    // Mark this typedef as having been generated.
+    ObjCForwardDecls.insert(ClassDecl);
+  }
+  SynthesizeObjCInternalStruct(ClassDecl, ResultStr);
+    
+  for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(*Context), 
+         E = ClassDecl->prop_end(*Context); I != E; ++I)
+    RewriteProperty(*I);
+  for (ObjCInterfaceDecl::instmeth_iterator 
+         I = ClassDecl->instmeth_begin(*Context), 
+         E = ClassDecl->instmeth_end(*Context);
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+  for (ObjCInterfaceDecl::classmeth_iterator 
+         I = ClassDecl->classmeth_begin(*Context), 
+         E = ClassDecl->classmeth_end(*Context); 
+       I != E; ++I)
+    RewriteMethodDeclaration(*I);
+
+  // Lastly, comment out the @end.
+  ReplaceText(ClassDecl->getAtEndLoc(), 0, "// ", 3);
+}
+
+Stmt *RewriteObjC::RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
+                                         SourceRange SrcRange) {
+  // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr.
+  // This allows us to reuse all the fun and games in SynthMessageExpr().
+  ObjCPropertyRefExpr *PropRefExpr = dyn_cast<ObjCPropertyRefExpr>(BinOp->getLHS());
+  ObjCMessageExpr *MsgExpr;
+  ObjCPropertyDecl *PDecl = PropRefExpr->getProperty();
+  llvm::SmallVector<Expr *, 1> ExprVec;
+  ExprVec.push_back(newStmt);
+  
+  Stmt *Receiver = PropRefExpr->getBase();
+  ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(Receiver);
+  if (PRE && PropGetters[PRE]) {
+    // This allows us to handle chain/nested property getters.
+    Receiver = PropGetters[PRE];
+  }
+  MsgExpr = new (Context) ObjCMessageExpr(dyn_cast<Expr>(Receiver), 
+                                PDecl->getSetterName(), PDecl->getType(), 
+                                PDecl->getSetterMethodDecl(), 
+                                SourceLocation(), SourceLocation(), 
+                                &ExprVec[0], 1);
+  Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
+  
+  // Now do the actual rewrite.
+  ReplaceStmtWithRange(BinOp, ReplacingStmt, SrcRange);
+  //delete BinOp;
+  // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
+  // to things that stay around.
+  Context->Deallocate(MsgExpr);
+  return ReplacingStmt;
+}
+
+Stmt *RewriteObjC::RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr) {
+  // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr.
+  // This allows us to reuse all the fun and games in SynthMessageExpr().
+  ObjCMessageExpr *MsgExpr;
+  ObjCPropertyDecl *PDecl = PropRefExpr->getProperty();
+  
+  Stmt *Receiver = PropRefExpr->getBase();
+  
+  ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(Receiver);
+  if (PRE && PropGetters[PRE]) {
+    // This allows us to handle chain/nested property getters.
+    Receiver = PropGetters[PRE];
+  }
+  MsgExpr = new (Context) ObjCMessageExpr(dyn_cast<Expr>(Receiver), 
+                                PDecl->getGetterName(), PDecl->getType(), 
+                                PDecl->getGetterMethodDecl(), 
+                                SourceLocation(), SourceLocation(), 
+                                0, 0);
+
+  Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
+
+  if (!PropParentMap)
+    PropParentMap = new ParentMap(CurrentBody);
+
+  Stmt *Parent = PropParentMap->getParent(PropRefExpr);
+  if (Parent && isa<ObjCPropertyRefExpr>(Parent)) {
+    // We stash away the ReplacingStmt since actually doing the
+    // replacement/rewrite won't work for nested getters (e.g. obj.p.i)
+    PropGetters[PropRefExpr] = ReplacingStmt;
+    // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
+    // to things that stay around.
+    Context->Deallocate(MsgExpr);
+    return PropRefExpr; // return the original...
+  } else {
+    ReplaceStmt(PropRefExpr, ReplacingStmt);
+    // delete PropRefExpr; elsewhere...    
+    // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
+    // to things that stay around.
+    Context->Deallocate(MsgExpr);
+    return ReplacingStmt;
+  }
+}
+
+Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, 
+                                          SourceLocation OrigStart) {
+  ObjCIvarDecl *D = IV->getDecl();
+  if (CurMethodDef) {
+    if (const PointerType *pType = IV->getBase()->getType()->getAsPointerType()) {
+      ObjCInterfaceType *iFaceDecl =
+        dyn_cast<ObjCInterfaceType>(pType->getPointeeType());
+      // lookup which class implements the instance variable.
+      ObjCInterfaceDecl *clsDeclared = 0;
+      iFaceDecl->getDecl()->lookupInstanceVariable(*Context, 
+                                                   D->getIdentifier(), 
+                                                   clsDeclared);
+      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
+      
+      // Synthesize an explicit cast to gain access to the ivar.
+      std::string RecName = clsDeclared->getIdentifier()->getName();
+      RecName += "_IMPL";
+      IdentifierInfo *II = &Context->Idents.get(RecName.c_str());
+      RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                          SourceLocation(), II);
+      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      CastExpr *castExpr = new (Context) CStyleCastExpr(castT, IV->getBase(),
+                                                         castT,SourceLocation(),
+                                                         SourceLocation());
+      // Don't forget the parens to enforce the proper binding.
+      ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
+                                               IV->getBase()->getLocEnd(),
+                                               castExpr);
+      if (IV->isFreeIvar() && 
+          CurMethodDef->getClassInterface() == iFaceDecl->getDecl()) {
+        MemberExpr *ME = new (Context) MemberExpr(PE, true, D,
+                                                   IV->getLocation(),
+                                                   D->getType());
+        ReplaceStmt(IV, ME);
+        // delete IV; leak for now, see RewritePropertySetter() usage for more info.
+        return ME;
+      }
+       
+      ReplaceStmt(IV->getBase(), PE);
+      // Cannot delete IV->getBase(), since PE points to it.
+      // Replace the old base with the cast. This is important when doing
+      // embedded rewrites. For example, [newInv->_container addObject:0].
+      IV->setBase(PE); 
+      return IV;
+    }
+  } else { // we are outside a method.
+    assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method");
+      
+    // Explicit ivar refs need to have a cast inserted.
+    // FIXME: consider sharing some of this code with the code above.
+    if (const PointerType *pType = IV->getBase()->getType()->getAsPointerType()) {
+      ObjCInterfaceType *iFaceDecl = dyn_cast<ObjCInterfaceType>(pType->getPointeeType());
+      // lookup which class implements the instance variable.
+      ObjCInterfaceDecl *clsDeclared = 0;
+      iFaceDecl->getDecl()->lookupInstanceVariable(*Context, 
+                                                   D->getIdentifier(), 
+                                                   clsDeclared);
+      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
+      
+      // Synthesize an explicit cast to gain access to the ivar.
+      std::string RecName = clsDeclared->getIdentifier()->getName();
+      RecName += "_IMPL";
+      IdentifierInfo *II = &Context->Idents.get(RecName.c_str());
+      RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                          SourceLocation(), II);
+      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      CastExpr *castExpr = new (Context) CStyleCastExpr(castT, IV->getBase(),
+                                                        castT, SourceLocation(),
+                                                        SourceLocation());
+      // Don't forget the parens to enforce the proper binding.
+      ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
+                                    IV->getBase()->getLocEnd(), castExpr);
+      ReplaceStmt(IV->getBase(), PE);
+      // Cannot delete IV->getBase(), since PE points to it.
+      // Replace the old base with the cast. This is important when doing
+      // embedded rewrites. For example, [newInv->_container addObject:0].
+      IV->setBase(PE); 
+      return IV;
+    }
+  }
+  return IV;
+}
+
+/// SynthCountByEnumWithState - To print:
+/// ((unsigned int (*)
+///  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
+///  (void *)objc_msgSend)((id)l_collection, 
+///                        sel_registerName(
+///                          "countByEnumeratingWithState:objects:count:"), 
+///                        &enumState, 
+///                        (id *)items, (unsigned int)16)
+///
+void RewriteObjC::SynthCountByEnumWithState(std::string &buf) {
+  buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, "
+  "id *, unsigned int))(void *)objc_msgSend)";
+  buf += "\n\t\t";
+  buf += "((id)l_collection,\n\t\t";
+  buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
+  buf += "\n\t\t";
+  buf += "&enumState, "
+         "(id *)items, (unsigned int)16)";
+}
+
+/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
+/// statement to exit to its outer synthesized loop.
+///
+Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace break with goto __break_label
+  std::string buf;
+  
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("break"), buf.c_str(), buf.size());
+
+  return 0;
+}
+
+/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
+/// statement to continue with its inner synthesized loop.
+///
+Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace continue with goto __continue_label
+  std::string buf;
+  
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("continue"), buf.c_str(), buf.size());
+  
+  return 0;
+}
+
+/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
+///  It rewrites:
+/// for ( type elem in collection) { stmts; }
+ 
+/// Into:
+/// {
+///   type elem; 
+///   struct __objcFastEnumerationState enumState = { 0 };
+///   id items[16];
+///   id l_collection = (id)collection;
+///   unsigned long limit = [l_collection countByEnumeratingWithState:&enumState 
+///                                       objects:items count:16];
+/// if (limit) {
+///   unsigned long startMutations = *enumState.mutationsPtr;
+///   do {
+///        unsigned long counter = 0;
+///        do {
+///             if (startMutations != *enumState.mutationsPtr) 
+///               objc_enumerationMutation(l_collection);
+///             elem = (type)enumState.itemsPtr[counter++];
+///             stmts;
+///             __continue_label: ;
+///        } while (counter < limit);
+///   } while (limit = [l_collection countByEnumeratingWithState:&enumState 
+///                                  objects:items count:16]);
+///   elem = nil;
+///   __break_label: ;
+///  }
+///  else
+///       elem = nil;
+///  }
+///
+Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                                SourceLocation OrigEnd) {
+  assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty");
+  assert(isa<ObjCForCollectionStmt>(Stmts.back()) && 
+         "ObjCForCollectionStmt Statement stack mismatch");
+  assert(!ObjCBcLabelNo.empty() && 
+         "ObjCForCollectionStmt - Label No stack empty");
+  
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+  const char *elementName;
+  std::string elementTypeAsString;
+  std::string buf;
+  buf = "\n{\n\t";
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
+    // type elem;
+    NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
+    QualType ElementType = cast<ValueDecl>(D)->getType();
+    elementTypeAsString = ElementType.getAsString();
+    buf += elementTypeAsString;
+    buf += " ";
+    elementName = D->getNameAsCString();
+    buf += elementName;
+    buf += ";\n\t";
+  }
+  else {
+    DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
+    elementName = DR->getDecl()->getNameAsCString();
+    elementTypeAsString 
+      = cast<ValueDecl>(DR->getDecl())->getType().getAsString();
+  }
+  
+  // struct __objcFastEnumerationState enumState = { 0 };
+  buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
+  // id items[16];
+  buf += "id items[16];\n\t";
+  // id l_collection = (id)
+  buf += "id l_collection = (id)";
+  // Find start location of 'collection' the hard way!
+  const char *startCollectionBuf = startBuf;
+  startCollectionBuf += 3;  // skip 'for'
+  startCollectionBuf = strchr(startCollectionBuf, '(');
+  startCollectionBuf++; // skip '('
+  // find 'in' and skip it.
+  while (*startCollectionBuf != ' ' ||
+         *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' ||
+         (*(startCollectionBuf+3) != ' ' &&
+          *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '('))
+    startCollectionBuf++;
+  startCollectionBuf += 3;
+  
+  // Replace: "for (type element in" with string constructed thus far. 
+  ReplaceText(startLoc, startCollectionBuf - startBuf,
+              buf.c_str(), buf.size());
+  // Replace ')' in for '(' type elem in collection ')' with ';'
+  SourceLocation rightParenLoc = S->getRParenLoc();
+  const char *rparenBuf = SM->getCharacterData(rightParenLoc);
+  SourceLocation lparenLoc = startLoc.getFileLocWithOffset(rparenBuf-startBuf);
+  buf = ";\n\t";
+  
+  // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
+  //                                   objects:items count:16];
+  // which is synthesized into:
+  // unsigned int limit = 
+  // ((unsigned int (*)
+  //  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
+  //  (void *)objc_msgSend)((id)l_collection, 
+  //                        sel_registerName(
+  //                          "countByEnumeratingWithState:objects:count:"), 
+  //                        (struct __objcFastEnumerationState *)&state, 
+  //                        (id *)items, (unsigned int)16);
+  buf += "unsigned long limit =\n\t\t";
+  SynthCountByEnumWithState(buf);
+  buf += ";\n\t";
+  /// if (limit) {
+  ///   unsigned long startMutations = *enumState.mutationsPtr;
+  ///   do {
+  ///        unsigned long counter = 0;
+  ///        do {
+  ///             if (startMutations != *enumState.mutationsPtr) 
+  ///               objc_enumerationMutation(l_collection);
+  ///             elem = (type)enumState.itemsPtr[counter++];
+  buf += "if (limit) {\n\t";
+  buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
+  buf += "do {\n\t\t";
+  buf += "unsigned long counter = 0;\n\t\t";
+  buf += "do {\n\t\t\t";
+  buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
+  buf += "objc_enumerationMutation(l_collection);\n\t\t\t";
+  buf += elementName;
+  buf += " = (";
+  buf += elementTypeAsString;
+  buf += ")enumState.itemsPtr[counter++];";
+  // Replace ')' in for '(' type elem in collection ')' with all of these.
+  ReplaceText(lparenLoc, 1, buf.c_str(), buf.size());
+  
+  ///            __continue_label: ;
+  ///        } while (counter < limit);
+  ///   } while (limit = [l_collection countByEnumeratingWithState:&enumState 
+  ///                                  objects:items count:16]);
+  ///   elem = nil;
+  ///   __break_label: ;
+  ///  }
+  ///  else
+  ///       elem = nil;
+  ///  }
+  /// 
+  buf = ";\n\t";
+  buf += "__continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;";
+  buf += "\n\t\t";
+  buf += "} while (counter < limit);\n\t";
+  buf += "} while (limit = ";
+  SynthCountByEnumWithState(buf);
+  buf += ");\n\t";
+  buf += elementName;
+  buf += " = ((id)0);\n\t";
+  buf += "__break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;\n\t";
+  buf += "}\n\t";
+  buf += "else\n\t\t";
+  buf += elementName;
+  buf += " = ((id)0);\n";
+  buf += "}\n";
+  
+  // Insert all these *after* the statement body.
+  // FIXME: If this should support Obj-C++, support CXXTryStmt
+  if (isa<CompoundStmt>(S->getBody())) {
+    SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(1);
+    InsertText(endBodyLoc, buf.c_str(), buf.size());
+  } else {
+    /* Need to treat single statements specially. For example:
+     *
+     *     for (A *a in b) if (stuff()) break;
+     *     for (A *a in b) xxxyy;
+     *
+     * The following code simply scans ahead to the semi to find the actual end.
+     */
+    const char *stmtBuf = SM->getCharacterData(OrigEnd);
+    const char *semiBuf = strchr(stmtBuf, ';');
+    assert(semiBuf && "Can't find ';'");
+    SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(semiBuf-stmtBuf+1);
+    InsertText(endBodyLoc, buf.c_str(), buf.size());
+  }
+  Stmts.pop_back();
+  ObjCBcLabelNo.pop_back();
+  return 0;
+}
+
+/// RewriteObjCSynchronizedStmt - 
+/// This routine rewrites @synchronized(expr) stmt;
+/// into:
+/// objc_sync_enter(expr);
+/// @try stmt @finally { objc_sync_exit(expr); }
+///
+Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+  
+  assert((*startBuf == '@') && "bogus @synchronized location");
+  
+  std::string buf; 
+  buf = "objc_sync_enter((id)";
+  const char *lparenBuf = startBuf;
+  while (*lparenBuf != '(') lparenBuf++;
+  ReplaceText(startLoc, lparenBuf-startBuf+1, buf.c_str(), buf.size());
+  // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since 
+  // the sync expression is typically a message expression that's already 
+  // been rewritten! (which implies the SourceLocation's are invalid).
+  SourceLocation endLoc = S->getSynchBody()->getLocStart();
+  const char *endBuf = SM->getCharacterData(endLoc);
+  while (*endBuf != ')') endBuf--;
+  SourceLocation rparenLoc = startLoc.getFileLocWithOffset(endBuf-startBuf);
+  buf = ");\n";
+  // declare a new scope with two variables, _stack and _rethrow.
+  buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n";
+  buf += "int buf[18/*32-bit i386*/];\n";
+  buf += "char *pointers[4];} _stack;\n";
+  buf += "id volatile _rethrow = 0;\n";
+  buf += "objc_exception_try_enter(&_stack);\n";
+  buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
+  ReplaceText(rparenLoc, 1, buf.c_str(), buf.size());
+  startLoc = S->getSynchBody()->getLocEnd();
+  startBuf = SM->getCharacterData(startLoc);
+  
+  assert((*startBuf == '}') && "bogus @synchronized block");
+  SourceLocation lastCurlyLoc = startLoc;
+  buf = "}\nelse {\n";
+  buf += "  _rethrow = objc_exception_extract(&_stack);\n";
+  buf += "}\n";
+  buf += "{ /* implicit finally clause */\n";
+  buf += "  if (!_rethrow) objc_exception_try_exit(&_stack);\n";
+  buf += "  objc_sync_exit(";
+  Expr *syncExpr = new (Context) CStyleCastExpr(Context->getObjCIdType(), 
+                                                S->getSynchExpr(), 
+                                                Context->getObjCIdType(),
+                                                SourceLocation(),
+                                                SourceLocation());
+  std::string syncExprBufS;
+  llvm::raw_string_ostream syncExprBuf(syncExprBufS);
+  syncExpr->printPretty(syncExprBuf);
+  buf += syncExprBuf.str();
+  buf += ");\n";
+  buf += "  if (_rethrow) objc_exception_throw(_rethrow);\n";
+  buf += "}\n";
+  buf += "}";
+  
+  ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
+  return 0;
+}
+
+void RewriteObjC::WarnAboutReturnGotoContinueOrBreakStmts(Stmt *S) {  
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI)
+      WarnAboutReturnGotoContinueOrBreakStmts(*CI);
+
+  if (isa<ReturnStmt>(S) || isa<ContinueStmt>(S) || 
+      isa<BreakStmt>(S) || isa<GotoStmt>(S)) {
+    Diags.Report(Context->getFullLoc(S->getLocStart()), 
+                 TryFinallyContainsReturnDiag);
+  }
+  return;
+}
+
+Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+  
+  assert((*startBuf == '@') && "bogus @try location");
+
+  std::string buf;
+  // declare a new scope with two variables, _stack and _rethrow.
+  buf = "/* @try scope begin */ { struct _objc_exception_data {\n";
+  buf += "int buf[18/*32-bit i386*/];\n";
+  buf += "char *pointers[4];} _stack;\n";
+  buf += "id volatile _rethrow = 0;\n";
+  buf += "objc_exception_try_enter(&_stack);\n";
+  buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
+
+  ReplaceText(startLoc, 4, buf.c_str(), buf.size());
+  
+  startLoc = S->getTryBody()->getLocEnd();
+  startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '}') && "bogus @try block");
+  
+  SourceLocation lastCurlyLoc = startLoc;
+  ObjCAtCatchStmt *catchList = S->getCatchStmts();
+  if (catchList) {
+    startLoc = startLoc.getFileLocWithOffset(1);
+    buf = " /* @catch begin */ else {\n";
+    buf += " id _caught = objc_exception_extract(&_stack);\n";
+    buf += " objc_exception_try_enter (&_stack);\n";
+    buf += " if (_setjmp(_stack.buf))\n";
+    buf += "   _rethrow = objc_exception_extract(&_stack);\n";
+    buf += " else { /* @catch continue */";
+    
+    InsertText(startLoc, buf.c_str(), buf.size());
+  } else { /* no catch list */
+    buf = "}\nelse {\n";
+    buf += "  _rethrow = objc_exception_extract(&_stack);\n";
+    buf += "}";
+    ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
+  }
+  bool sawIdTypedCatch = false;
+  Stmt *lastCatchBody = 0;
+  while (catchList) {
+    ParmVarDecl *catchDecl = catchList->getCatchParamDecl();
+
+    if (catchList == S->getCatchStmts()) 
+      buf = "if ("; // we are generating code for the first catch clause
+    else
+      buf = "else if (";
+    startLoc = catchList->getLocStart();
+    startBuf = SM->getCharacterData(startLoc);
+    
+    assert((*startBuf == '@') && "bogus @catch location");
+    
+    const char *lParenLoc = strchr(startBuf, '(');
+
+    if (catchList->hasEllipsis()) {
+      // Now rewrite the body...
+      lastCatchBody = catchList->getCatchBody();
+      SourceLocation bodyLoc = lastCatchBody->getLocStart();
+      const char *bodyBuf = SM->getCharacterData(bodyLoc);
+      assert(*SM->getCharacterData(catchList->getRParenLoc()) == ')' &&
+             "bogus @catch paren location");
+      assert((*bodyBuf == '{') && "bogus @catch body location");
+      
+      buf += "1) { id _tmp = _caught;";
+      Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, 
+                          buf.c_str(), buf.size());      
+    } else if (catchDecl) {
+      QualType t = catchDecl->getType();
+      if (t == Context->getObjCIdType()) {
+        buf += "1) { ";
+        ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size());
+        sawIdTypedCatch = true;
+      } else if (const PointerType *pType = t->getAsPointerType()) { 
+        ObjCInterfaceType *cls; // Should be a pointer to a class.
+        
+        cls = dyn_cast<ObjCInterfaceType>(pType->getPointeeType().getTypePtr());
+        if (cls) {
+          buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
+          buf += cls->getDecl()->getNameAsString();
+          buf += "\"), (struct objc_object *)_caught)) { ";
+          ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size());
+        }
+      }
+      // Now rewrite the body...
+      lastCatchBody = catchList->getCatchBody();
+      SourceLocation rParenLoc = catchList->getRParenLoc();
+      SourceLocation bodyLoc = lastCatchBody->getLocStart();
+      const char *bodyBuf = SM->getCharacterData(bodyLoc);
+      const char *rParenBuf = SM->getCharacterData(rParenLoc);
+      assert((*rParenBuf == ')') && "bogus @catch paren location");
+      assert((*bodyBuf == '{') && "bogus @catch body location");
+        
+      buf = " = _caught;";
+      // Here we replace ") {" with "= _caught;" (which initializes and 
+      // declares the @catch parameter).
+      ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, buf.c_str(), buf.size());
+    } else {
+      assert(false && "@catch rewrite bug");
+    }
+    // make sure all the catch bodies get rewritten!
+    catchList = catchList->getNextCatchStmt();
+  }
+  // Complete the catch list...
+  if (lastCatchBody) {
+    SourceLocation bodyLoc = lastCatchBody->getLocEnd();
+    assert(*SM->getCharacterData(bodyLoc) == '}' &&
+           "bogus @catch body location");
+  
+    // Insert the last (implicit) else clause *before* the right curly brace.
+    bodyLoc = bodyLoc.getFileLocWithOffset(-1);
+    buf = "} /* last catch end */\n";
+    buf += "else {\n";
+    buf += " _rethrow = _caught;\n";
+    buf += " objc_exception_try_exit(&_stack);\n";
+    buf += "} } /* @catch end */\n";
+    if (!S->getFinallyStmt())
+      buf += "}\n";
+    InsertText(bodyLoc, buf.c_str(), buf.size());
+    
+    // Set lastCurlyLoc
+    lastCurlyLoc = lastCatchBody->getLocEnd();
+  }
+  if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) {
+    startLoc = finalStmt->getLocStart();
+    startBuf = SM->getCharacterData(startLoc);
+    assert((*startBuf == '@') && "bogus @finally start");
+    
+    buf = "/* @finally */";
+    ReplaceText(startLoc, 8, buf.c_str(), buf.size());
+    
+    Stmt *body = finalStmt->getFinallyBody();
+    SourceLocation startLoc = body->getLocStart();
+    SourceLocation endLoc = body->getLocEnd();
+    assert(*SM->getCharacterData(startLoc) == '{' &&
+           "bogus @finally body location");
+    assert(*SM->getCharacterData(endLoc) == '}' && 
+           "bogus @finally body location");
+  
+    startLoc = startLoc.getFileLocWithOffset(1);
+    buf = " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
+    InsertText(startLoc, buf.c_str(), buf.size());
+    endLoc = endLoc.getFileLocWithOffset(-1);
+    buf = " if (_rethrow) objc_exception_throw(_rethrow);\n";
+    InsertText(endLoc, buf.c_str(), buf.size());
+    
+    // Set lastCurlyLoc
+    lastCurlyLoc = body->getLocEnd();
+    
+    // Now check for any return/continue/go statements within the @try.
+    WarnAboutReturnGotoContinueOrBreakStmts(S->getTryBody());
+  } else { /* no finally clause - make sure we synthesize an implicit one */
+    buf = "{ /* implicit finally clause */\n";
+    buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
+    buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
+    buf += "}";
+    ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
+  }
+  // Now emit the final closing curly brace...
+  lastCurlyLoc = lastCurlyLoc.getFileLocWithOffset(1);
+  buf = " } /* @try scope end */\n";
+  InsertText(lastCurlyLoc, buf.c_str(), buf.size());
+  return 0;
+}
+
+Stmt *RewriteObjC::RewriteObjCCatchStmt(ObjCAtCatchStmt *S) {
+  return 0;
+}
+
+Stmt *RewriteObjC::RewriteObjCFinallyStmt(ObjCAtFinallyStmt *S) {
+  return 0;
+}
+
+// This can't be done with ReplaceStmt(S, ThrowExpr), since 
+// the throw expression is typically a message expression that's already 
+// been rewritten! (which implies the SourceLocation's are invalid).
+Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+  
+  assert((*startBuf == '@') && "bogus @throw location");
+
+  std::string buf;
+  /* void objc_exception_throw(id) __attribute__((noreturn)); */
+  if (S->getThrowExpr())
+    buf = "objc_exception_throw(";
+  else // add an implicit argument
+    buf = "objc_exception_throw(_caught";
+  
+  // handle "@  throw" correctly.
+  const char *wBuf = strchr(startBuf, 'w');
+  assert((*wBuf == 'w') && "@throw: can't find 'w'");
+  ReplaceText(startLoc, wBuf-startBuf+1, buf.c_str(), buf.size());
+  
+  const char *semiBuf = strchr(startBuf, ';');
+  assert((*semiBuf == ';') && "@throw: can't find ';'");
+  SourceLocation semiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf);
+  buf = ");";
+  ReplaceText(semiLoc, 1, buf.c_str(), buf.size());
+  return 0;
+}
+
+Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
+  // Create a new string expression.
+  QualType StrType = Context->getPointerType(Context->CharTy);
+  std::string StrEncoding;
+  Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
+  Expr *Replacement = StringLiteral::Create(*Context,StrEncoding.c_str(),
+                                            StrEncoding.length(), false,StrType,
+                                            SourceLocation());
+  ReplaceStmt(Exp, Replacement);
+  
+  // Replace this subexpr in the parent.
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
+  return Replacement;
+}
+
+Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
+  // Create a call to sel_registerName("selName").
+  llvm::SmallVector<Expr*, 8> SelExprs;
+  QualType argType = Context->getPointerType(Context->CharTy);
+  SelExprs.push_back(StringLiteral::Create(*Context, 
+                                       Exp->getSelector().getAsString().c_str(),
+                                       Exp->getSelector().getAsString().size(),
+                                       false, argType, SourceLocation()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size());
+  ReplaceStmt(Exp, SelExp);
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
+  return SelExp;
+}
+
+CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
+  FunctionDecl *FD, Expr **args, unsigned nargs) {
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = FD->getType();
+  
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, msgSendType, SourceLocation());
+                                     
+  // Now, we cast the reference to a pointer to the objc_msgSend type.
+  QualType pToFunc = Context->getPointerType(msgSendType);
+  ImplicitCastExpr *ICE = new (Context) ImplicitCastExpr(pToFunc, DRE, 
+                                               /*isLvalue=*/false);
+  
+  const FunctionType *FT = msgSendType->getAsFunctionType();
+  
+  return new (Context) CallExpr(*Context, ICE, args, nargs, FT->getResultType(),
+                                SourceLocation());
+}
+
+static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
+                                const char *&startRef, const char *&endRef) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '<')
+      startRef = startBuf; // mark the start.
+    if (*startBuf == '>') {
+      if (startRef && *startRef == '<') {
+        endRef = startBuf; // mark the end.
+        return true;
+      }
+      return false;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+static void scanToNextArgument(const char *&argRef) {
+  int angle = 0;
+  while (*argRef != ')' && (*argRef != ',' || angle > 0)) {
+    if (*argRef == '<')
+      angle++;
+    else if (*argRef == '>')
+      angle--;
+    argRef++;
+  }
+  assert(angle == 0 && "scanToNextArgument - bad protocol type syntax");
+}
+
+bool RewriteObjC::needToScanForQualifiers(QualType T) {
+  
+  if (T->isObjCQualifiedIdType())
+    return true;
+  
+  if (const PointerType *pType = T->getAsPointerType()) {
+    Type *pointeeType = pType->getPointeeType().getTypePtr();
+    if (isa<ObjCQualifiedInterfaceType>(pointeeType))
+      return true; // we have "Class <Protocol> *".
+  }
+  return false;
+}
+
+void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
+  QualType Type = E->getType();
+  if (needToScanForQualifiers(Type)) {
+    SourceLocation Loc, EndLoc;
+    
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) {
+      Loc = ECE->getLParenLoc();
+      EndLoc = ECE->getRParenLoc();
+    } else {
+      Loc = E->getLocStart();
+      EndLoc = E->getLocEnd();
+    }
+    // This will defend against trying to rewrite synthesized expressions.
+    if (Loc.isInvalid() || EndLoc.isInvalid())
+      return;
+
+    const char *startBuf = SM->getCharacterData(Loc);
+    const char *endBuf = SM->getCharacterData(EndLoc);
+    const char *startRef = 0, *endRef = 0;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-startBuf);
+      SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-startBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*", 2);
+      InsertText(GreaterLoc, "*/", 2);
+    }
+  }
+}
+
+void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
+  SourceLocation Loc;
+  QualType Type;
+  const FunctionProtoType *proto = 0;
+  if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
+    Loc = VD->getLocation();
+    Type = VD->getType();
+  }
+  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
+    Loc = FD->getLocation();
+    // Check for ObjC 'id' and class types that have been adorned with protocol
+    // information (id<p>, C<p>*). The protocol references need to be rewritten!
+    const FunctionType *funcType = FD->getType()->getAsFunctionType();
+    assert(funcType && "missing function type");
+    proto = dyn_cast<FunctionProtoType>(funcType);
+    if (!proto)
+      return;
+    Type = proto->getResultType();
+  }
+  else
+    return;
+  
+  if (needToScanForQualifiers(Type)) {
+    // Since types are unique, we need to scan the buffer.
+    
+    const char *endBuf = SM->getCharacterData(Loc);
+    const char *startBuf = endBuf;
+    while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart)
+      startBuf--; // scan backward (from the decl location) for return type.
+    const char *startRef = 0, *endRef = 0;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-endBuf);
+      SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-endBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*", 2);
+      InsertText(GreaterLoc, "*/", 2);
+    }
+  }
+  if (!proto)
+      return; // most likely, was a variable
+  // Now check arguments.
+  const char *startBuf = SM->getCharacterData(Loc);
+  const char *startFuncBuf = startBuf;
+  for (unsigned i = 0; i < proto->getNumArgs(); i++) {
+    if (needToScanForQualifiers(proto->getArgType(i))) {
+      // Since types are unique, we need to scan the buffer.
+      
+      const char *endBuf = startBuf;
+      // scan forward (from the decl location) for argument types.
+      scanToNextArgument(endBuf);
+      const char *startRef = 0, *endRef = 0;
+      if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+        // Get the locations of the startRef, endRef.
+        SourceLocation LessLoc = 
+          Loc.getFileLocWithOffset(startRef-startFuncBuf);
+        SourceLocation GreaterLoc = 
+          Loc.getFileLocWithOffset(endRef-startFuncBuf+1);
+        // Comment out the protocol references.
+        InsertText(LessLoc, "/*", 2);
+        InsertText(GreaterLoc, "*/", 2);
+      }
+      startBuf = ++endBuf;
+    }
+    else {
+      // If the function name is derived from a macro expansion, then the
+      // argument buffer will not follow the name. Need to speak with Chris.
+      while (*startBuf && *startBuf != ')' && *startBuf != ',')
+        startBuf++; // scan forward (from the decl location) for argument types.
+      startBuf++;
+    }
+  }
+}
+
+// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
+void RewriteObjC::SynthSelGetUidFunctionDecl() {
+  IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(
+    Context->CharTy.getQualifiedType(QualType::Const)));
+  QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(),
+                                                   &ArgTys[0], ArgTys.size(),
+                                                   false /*isVariadic*/, 0);
+  SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                           SourceLocation(), 
+                                           SelGetUidIdent, getFuncType,
+                                           FunctionDecl::Extern, false);
+}
+
+void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
+  // declared in <objc/objc.h>
+  if (FD->getIdentifier() &&
+      strcmp(FD->getNameAsCString(), "sel_registerName") == 0) {
+    SelGetUidFunctionDecl = FD;
+    return;
+  }
+  RewriteObjCQualifiedInterfaceTypes(FD);
+}
+
+// SynthSuperContructorFunctionDecl - id objc_super(id obj, id super);
+void RewriteObjC::SynthSuperContructorFunctionDecl() {
+  if (SuperContructorFunctionDecl)
+    return;
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  ArgTys.push_back(argT);
+  QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
+                                                  &ArgTys[0], ArgTys.size(),
+                                                  false, 0);
+  SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                         SourceLocation(), 
+                                         msgSendIdent, msgSendType,
+                                         FunctionDecl::Extern, false);
+}
+
+// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
+  llvm::SmallVector<QualType, 16> 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*/, 0);
+  MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                         SourceLocation(),
+                                         msgSendIdent, msgSendType,
+                                         FunctionDecl::Extern, false);
+}
+
+// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
+void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                      SourceLocation(),
+                                      &Context->Idents.get("objc_super"));
+  QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
+  assert(!argT.isNull() && "Can't build 'struct objc_super *' 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*/, 0);
+  MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                              SourceLocation(), 
+                                              msgSendIdent, msgSendType,
+                                              FunctionDecl::Extern, false);
+}
+
+// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
+  llvm::SmallVector<QualType, 16> 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*/, 0);
+  MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                         SourceLocation(), 
+                                         msgSendIdent, msgSendType,
+                                         FunctionDecl::Extern, false);
+}
+
+// SynthMsgSendSuperStretFunctionDecl - 
+// id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...);
+void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = 
+    &Context->Idents.get("objc_msgSendSuper_stret");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                      SourceLocation(),
+                                      &Context->Idents.get("objc_super"));
+  QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
+  assert(!argT.isNull() && "Can't build 'struct objc_super *' 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*/, 0);
+  MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                       SourceLocation(), 
+                                              msgSendIdent, msgSendType,
+                                              FunctionDecl::Extern, false);
+}
+
+// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
+  llvm::SmallVector<QualType, 16> 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->DoubleTy,
+                                                  &ArgTys[0], ArgTys.size(),
+                                                  true /*isVariadic*/, 0);
+  MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                              SourceLocation(), 
+                                              msgSendIdent, msgSendType,
+                                              FunctionDecl::Extern, false);
+}
+
+// SynthGetClassFunctionDecl - id objc_getClass(const char *name);
+void RewriteObjC::SynthGetClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(
+                     Context->CharTy.getQualifiedType(QualType::Const)));
+  QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
+                                                   &ArgTys[0], ArgTys.size(),
+                                                   false /*isVariadic*/, 0);
+  GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                          SourceLocation(), 
+                                          getClassIdent, getClassType,
+                                          FunctionDecl::Extern, false);
+}
+
+// SynthGetMetaClassFunctionDecl - id objc_getClass(const char *name);
+void RewriteObjC::SynthGetMetaClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
+  llvm::SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(
+                     Context->CharTy.getQualifiedType(QualType::Const)));
+  QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
+                                                   &ArgTys[0], ArgTys.size(),
+                                                   false /*isVariadic*/, 0);
+  GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                              SourceLocation(), 
+                                              getClassIdent, getClassType,
+                                              FunctionDecl::Extern, false);
+}
+
+Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
+  QualType strType = getConstantStringStructType();
+
+  std::string S = "__NSConstantStringImpl_";
+
+  std::string tmpName = InFileName;
+  unsigned i;
+  for (i=0; i < tmpName.length(); i++) {
+    char c = tmpName.at(i);
+    // replace any non alphanumeric characters with '_'.
+    if (!isalpha(c) && (c < '0' || c > '9'))
+      tmpName[i] = '_';
+  }
+  S += tmpName;
+  S += "_";
+  S += utostr(NumObjCStringLiterals++);
+
+  Preamble += "static __NSConstantStringImpl " + S;
+  Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
+  Preamble += "0x000007c8,"; // utf8_str
+  // The pretty printer for StringLiteral handles escape characters properly.
+  std::string prettyBufS;
+  llvm::raw_string_ostream prettyBuf(prettyBufS);
+  Exp->getString()->printPretty(prettyBuf);
+  Preamble += prettyBuf.str();
+  Preamble += ",";
+  // The minus 2 removes the begin/end double quotes.
+  Preamble += utostr(prettyBuf.str().size()-2) + "};\n";
+  
+  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 
+                                    &Context->Idents.get(S.c_str()), strType, 
+                                    VarDecl::Static);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, SourceLocation());
+  Expr *Unop = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
+                                 Context->getPointerType(DRE->getType()), 
+                                 SourceLocation());
+  // cast to NSConstantString *
+  CastExpr *cast = new (Context) CStyleCastExpr(Exp->getType(), Unop, 
+                                         Exp->getType(), SourceLocation(), SourceLocation());
+  ReplaceStmt(Exp, cast);
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
+  return cast;
+}
+
+ObjCInterfaceDecl *RewriteObjC::isSuperReceiver(Expr *recExpr) {
+  // check if we are sending a message to 'super'
+  if (!CurMethodDef || !CurMethodDef->isInstanceMethod()) return 0;
+  
+  if (ObjCSuperExpr *Super = dyn_cast<ObjCSuperExpr>(recExpr)) {
+      const PointerType *PT = Super->getType()->getAsPointerType();
+      assert(PT);
+      ObjCInterfaceType *IT = cast<ObjCInterfaceType>(PT->getPointeeType());
+      return IT->getDecl();
+    }
+  return 0;
+}
+
+// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
+QualType RewriteObjC::getSuperStructType() {
+  if (!SuperStructDecl) {
+    SuperStructDecl = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                         SourceLocation(), 
+                                         &Context->Idents.get("objc_super"));
+    QualType FieldTypes[2];
+  
+    // struct objc_object *receiver;
+    FieldTypes[0] = Context->getObjCIdType();  
+    // struct objc_class *super;
+    FieldTypes[1] = Context->getObjCClassType();  
+
+    // Create fields
+    for (unsigned i = 0; i < 2; ++i) {
+      SuperStructDecl->addDecl(*Context,
+                               FieldDecl::Create(*Context, SuperStructDecl, 
+                                                 SourceLocation(), 0, 
+                                                 FieldTypes[i], /*BitWidth=*/0,
+                                                 /*Mutable=*/false));
+    }
+  
+    SuperStructDecl->completeDefinition(*Context);
+  }
+  return Context->getTagDeclType(SuperStructDecl);
+}
+
+QualType RewriteObjC::getConstantStringStructType() {
+  if (!ConstantStringDecl) {
+    ConstantStringDecl = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                            SourceLocation(), 
+                         &Context->Idents.get("__NSConstantStringImpl"));
+    QualType FieldTypes[4];
+  
+    // struct objc_object *receiver;
+    FieldTypes[0] = Context->getObjCIdType();  
+    // int flags;
+    FieldTypes[1] = Context->IntTy;  
+    // char *str;
+    FieldTypes[2] = Context->getPointerType(Context->CharTy);  
+    // long length;
+    FieldTypes[3] = Context->LongTy;  
+
+    // Create fields
+    for (unsigned i = 0; i < 4; ++i) {
+      ConstantStringDecl->addDecl(*Context,
+                                  FieldDecl::Create(*Context, 
+                                                    ConstantStringDecl, 
+                                                    SourceLocation(), 0,
+                                                    FieldTypes[i], 
+                                                    /*BitWidth=*/0,
+                                                    /*Mutable=*/true));
+    }
+
+    ConstantStringDecl->completeDefinition(*Context);
+  }
+  return Context->getTagDeclType(ConstantStringDecl);
+}
+
+Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!MsgSendSuperFunctionDecl)
+    SynthMsgSendSuperFunctionDecl();
+  if (!MsgSendStretFunctionDecl)
+    SynthMsgSendStretFunctionDecl();
+  if (!MsgSendSuperStretFunctionDecl)
+    SynthMsgSendSuperStretFunctionDecl();
+  if (!MsgSendFpretFunctionDecl)
+    SynthMsgSendFpretFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  if (!GetMetaClassFunctionDecl)
+    SynthGetMetaClassFunctionDecl();
+  
+  // default to objc_msgSend().
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  // May need to use objc_msgSend_stret() as well.
+  FunctionDecl *MsgSendStretFlavor = 0;
+  if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
+    QualType resultType = mDecl->getResultType();
+    if (resultType->isStructureType() || resultType->isUnionType())
+      MsgSendStretFlavor = MsgSendStretFunctionDecl;
+    else if (resultType->isRealFloatingType())
+      MsgSendFlavor = MsgSendFpretFunctionDecl;
+  }
+  
+  // Synthesize a call to objc_msgSend().
+  llvm::SmallVector<Expr*, 8> MsgExprs;
+  IdentifierInfo *clsName = Exp->getClassName();
+  
+  // Derive/push the receiver/selector, 2 implicit arguments to objc_msgSend().
+  if (clsName) { // class message.
+    // FIXME: We need to fix Sema (and the AST for ObjCMessageExpr) to handle
+    // the 'super' idiom within a class method.
+    if (!strcmp(clsName->getName(), "super")) {
+      MsgSendFlavor = MsgSendSuperFunctionDecl;
+      if (MsgSendStretFlavor)
+        MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+      assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+      
+      ObjCInterfaceDecl *SuperDecl = 
+        CurMethodDef->getClassInterface()->getSuperClass();
+
+      llvm::SmallVector<Expr*, 4> InitExprs;
+      
+      // set the receiver to self, the first argument to all methods.
+      InitExprs.push_back(
+        new (Context) CStyleCastExpr(Context->getObjCIdType(), 
+                     new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 
+                                     Context->getObjCIdType(),
+                                     SourceLocation()),
+                     Context->getObjCIdType(),
+                     SourceLocation(), SourceLocation())); // set the 'receiver'.
+
+      llvm::SmallVector<Expr*, 8> ClsExprs;
+      QualType argType = Context->getPointerType(Context->CharTy);
+      ClsExprs.push_back(StringLiteral::Create(*Context,
+                                        SuperDecl->getIdentifier()->getName(), 
+                                        SuperDecl->getIdentifier()->getLength(),
+                                        false, argType, SourceLocation()));
+      CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
+                                                   &ClsExprs[0], 
+                                                   ClsExprs.size());
+      // To turn off a warning, type-cast to 'id'
+      InitExprs.push_back( // set 'super class', using objc_getClass().
+        new (Context) CStyleCastExpr(Context->getObjCIdType(), 
+                              Cls, Context->getObjCIdType(),
+                              SourceLocation(), SourceLocation())); 
+      // struct objc_super
+      QualType superType = getSuperStructType();
+      Expr *SuperRep;
+      
+      if (LangOpts.Microsoft) {
+        SynthSuperContructorFunctionDecl();
+        // Simulate a contructor call...
+        DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, 
+                                           superType, SourceLocation());
+        SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+                                          InitExprs.size(), 
+                                          superType, SourceLocation());
+        // The code for super is a little tricky to prevent collision with
+        // the structure definition in the header. The rewriter has it's own
+        // internal definition (__rw_objc_super) that is uses. This is why
+        // we need the cast below. For example:
+        // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+        //
+        SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                                 Context->getPointerType(SuperRep->getType()), 
+                                 SourceLocation());
+        SuperRep = new (Context) CStyleCastExpr(Context->getPointerType(superType), 
+                                 SuperRep, Context->getPointerType(superType),
+                                 SourceLocation(), SourceLocation()); 
+      } else {      
+        // (struct objc_super) { <exprs from above> }
+        InitListExpr *ILE = new (Context) InitListExpr(SourceLocation(), 
+                                             &InitExprs[0], InitExprs.size(), 
+                                             SourceLocation());
+        SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superType, ILE,
+                                           false);
+        // struct objc_super *
+        SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                                 Context->getPointerType(SuperRep->getType()), 
+                                 SourceLocation());
+      }
+      MsgExprs.push_back(SuperRep);
+    } else {
+      llvm::SmallVector<Expr*, 8> ClsExprs;
+      QualType argType = Context->getPointerType(Context->CharTy);
+      ClsExprs.push_back(StringLiteral::Create(*Context,
+                                               clsName->getName(), 
+                                               clsName->getLength(),
+                                               false, argType,
+                                               SourceLocation()));
+      CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                   &ClsExprs[0], 
+                                                   ClsExprs.size());
+      MsgExprs.push_back(Cls);
+    }
+  } else { // instance message.
+    Expr *recExpr = Exp->getReceiver();
+
+    if (ObjCInterfaceDecl *SuperDecl = isSuperReceiver(recExpr)) {
+      MsgSendFlavor = MsgSendSuperFunctionDecl;
+      if (MsgSendStretFlavor)
+        MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+      assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+      
+      llvm::SmallVector<Expr*, 4> InitExprs;
+      
+      InitExprs.push_back(
+        new (Context) CStyleCastExpr(Context->getObjCIdType(), 
+                     new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 
+                                     Context->getObjCIdType(),
+                                     SourceLocation()),
+                     Context->getObjCIdType(),
+                     SourceLocation(), SourceLocation())); // set the 'receiver'.
+      
+      llvm::SmallVector<Expr*, 8> ClsExprs;
+      QualType argType = Context->getPointerType(Context->CharTy);
+      ClsExprs.push_back(StringLiteral::Create(*Context, 
+                                        SuperDecl->getIdentifier()->getName(), 
+                                        SuperDecl->getIdentifier()->getLength(),
+                                        false, argType, SourceLocation()));
+      CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                   &ClsExprs[0], 
+                                                   ClsExprs.size());
+      // To turn off a warning, type-cast to 'id'
+      InitExprs.push_back(
+        // set 'super class', using objc_getClass().
+        new (Context) CStyleCastExpr(Context->getObjCIdType(), 
+        Cls, Context->getObjCIdType(), SourceLocation(), SourceLocation())); 
+      // struct objc_super
+      QualType superType = getSuperStructType();
+      Expr *SuperRep;
+      
+      if (LangOpts.Microsoft) {
+        SynthSuperContructorFunctionDecl();
+        // Simulate a contructor call...
+        DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, 
+                                           superType, SourceLocation());
+        SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+                                          InitExprs.size(), 
+                                          superType, SourceLocation());
+        // The code for super is a little tricky to prevent collision with
+        // the structure definition in the header. The rewriter has it's own
+        // internal definition (__rw_objc_super) that is uses. This is why
+        // we need the cast below. For example:
+        // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+        //
+        SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                                 Context->getPointerType(SuperRep->getType()), 
+                                 SourceLocation());
+        SuperRep = new (Context) CStyleCastExpr(Context->getPointerType(superType), 
+                                 SuperRep, Context->getPointerType(superType),
+                                 SourceLocation(), SourceLocation()); 
+      } else {
+        // (struct objc_super) { <exprs from above> }
+        InitListExpr *ILE = new (Context) InitListExpr(SourceLocation(), 
+                                             &InitExprs[0], InitExprs.size(), 
+                                             SourceLocation());
+        SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superType, ILE, false);
+      }
+      MsgExprs.push_back(SuperRep);
+    } else {
+      // Remove all type-casts because it may contain objc-style types; e.g.
+      // Foo<Proto> *.
+      while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
+        recExpr = CE->getSubExpr();
+      recExpr = new (Context) CStyleCastExpr(Context->getObjCIdType(), recExpr,
+                                      Context->getObjCIdType(), 
+                                      SourceLocation(), SourceLocation());
+      MsgExprs.push_back(recExpr);
+    }
+  }
+  // Create a call to sel_registerName("selName"), it will be the 2nd argument.
+  llvm::SmallVector<Expr*, 8> SelExprs;
+  QualType argType = Context->getPointerType(Context->CharTy);
+  SelExprs.push_back(StringLiteral::Create(*Context, 
+                                       Exp->getSelector().getAsString().c_str(),
+                                       Exp->getSelector().getAsString().size(),
+                                       false, argType, SourceLocation()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size());
+  MsgExprs.push_back(SelExp);
+  
+  // Now push any user supplied arguments.
+  for (unsigned i = 0; i < Exp->getNumArgs(); i++) {
+    Expr *userExpr = Exp->getArg(i);
+    // Make all implicit casts explicit...ICE comes in handy:-)
+    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
+      // Reuse the ICE type, it is exactly what the doctor ordered.
+      QualType type = ICE->getType()->isObjCQualifiedIdType()
+                                ? Context->getObjCIdType()
+                                : ICE->getType();
+      userExpr = new (Context) CStyleCastExpr(type, userExpr, type, SourceLocation(), SourceLocation());
+    }
+    // Make id<P...> cast into an 'id' cast.
+    else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
+      if (CE->getType()->isObjCQualifiedIdType()) {
+        while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
+          userExpr = CE->getSubExpr();
+        userExpr = new (Context) CStyleCastExpr(Context->getObjCIdType(), 
+                                userExpr, Context->getObjCIdType(), 
+                                SourceLocation(), SourceLocation());
+      }
+    } 
+    MsgExprs.push_back(userExpr);
+    // We've transferred the ownership to MsgExprs. For now, we *don't* null
+    // out the argument in the original expression (since we aren't deleting
+    // the ObjCMessageExpr). See RewritePropertySetter() usage for more info.
+    //Exp->setArg(i, 0);
+  }
+  // Generate the funky cast.
+  CastExpr *cast;
+  llvm::SmallVector<QualType, 8> ArgTypes;
+  QualType returnType;
+  
+  // Push 'id' and 'SEL', the 2 implicit arguments.
+  if (MsgSendFlavor == MsgSendSuperFunctionDecl)
+    ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
+  else
+    ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) {
+    // Push any user argument types.
+    for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
+         E = OMD->param_end(); PI != E; ++PI) {
+      QualType t = (*PI)->getType()->isObjCQualifiedIdType()
+                     ? Context->getObjCIdType() 
+                     : (*PI)->getType();
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (isTopLevelBlockPointerType(t)) {
+        const BlockPointerType *BPT = t->getAsBlockPointerType();
+        t = Context->getPointerType(BPT->getPointeeType());
+      }
+      ArgTypes.push_back(t);
+    }
+    returnType = OMD->getResultType()->isObjCQualifiedIdType()
+                   ? Context->getObjCIdType() : OMD->getResultType();
+  } else {
+    returnType = Context->getObjCIdType();
+  }
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+  
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType, 
+                                     SourceLocation());
+
+  // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid). 
+  // If we don't do this cast, we get the following bizarre warning/note:
+  // xx.m:13: warning: function called through a non-compatible type
+  // xx.m:13: note: if this code is reached, the program will abort
+  cast = new (Context) CStyleCastExpr(Context->getPointerType(Context->VoidTy), DRE, 
+                               Context->getPointerType(Context->VoidTy),
+                               SourceLocation(), SourceLocation());
+    
+  // Now do the "normal" pointer to function cast.
+  QualType castType = Context->getFunctionType(returnType, 
+    &ArgTypes[0], ArgTypes.size(),
+    // If we don't have a method decl, force a variadic cast.
+    Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true, 0);
+  castType = Context->getPointerType(castType);
+  cast = new (Context) CStyleCastExpr(castType, cast, castType, SourceLocation(), SourceLocation());
+
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast);
+  
+  const FunctionType *FT = msgSendType->getAsFunctionType();
+  CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
+                                        MsgExprs.size(), 
+                                        FT->getResultType(), SourceLocation());
+  Stmt *ReplacingStmt = CE;
+  if (MsgSendStretFlavor) {
+    // We have the method which returns a struct/union. Must also generate
+    // call to objc_msgSend_stret and hang both varieties on a conditional
+    // expression which dictate which one to envoke depending on size of
+    // method's return type.
+    
+    // Create a reference to the objc_msgSend_stret() declaration.
+    DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, msgSendType, 
+                                         SourceLocation());
+    // Need to cast objc_msgSend_stret to "void *" (see above comment).
+    cast = new (Context) CStyleCastExpr(Context->getPointerType(Context->VoidTy), STDRE, 
+                                 Context->getPointerType(Context->VoidTy),
+                                 SourceLocation(), SourceLocation());
+    // Now do the "normal" pointer to function cast.
+    castType = Context->getFunctionType(returnType, 
+      &ArgTypes[0], ArgTypes.size(),
+      Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false, 0);
+    castType = Context->getPointerType(castType);
+    cast = new (Context) CStyleCastExpr(castType, cast, castType, SourceLocation(), SourceLocation());
+    
+    // Don't forget the parens to enforce the proper binding.
+    PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast);
+    
+    FT = msgSendType->getAsFunctionType();
+    CallExpr *STCE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
+                                            MsgExprs.size(), 
+                                            FT->getResultType(), SourceLocation());
+    
+    // Build sizeof(returnType)
+    SizeOfAlignOfExpr *sizeofExpr = new (Context) SizeOfAlignOfExpr(true, 
+                                      returnType,
+                                      Context->getSizeType(),
+                                      SourceLocation(), SourceLocation());
+    // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
+    // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases.
+    // For X86 it is more complicated and some kind of target specific routine
+    // is needed to decide what to do.
+    unsigned IntSize = 
+      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+    IntegerLiteral *limit = new (Context) IntegerLiteral(llvm::APInt(IntSize, 8), 
+                                               Context->IntTy,
+                                               SourceLocation());
+    BinaryOperator *lessThanExpr = new (Context) BinaryOperator(sizeofExpr, limit, 
+                                                      BinaryOperator::LE, 
+                                                      Context->IntTy, 
+                                                      SourceLocation());
+    // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
+    ConditionalOperator *CondExpr = 
+      new (Context) ConditionalOperator(lessThanExpr, CE, STCE, returnType);
+    ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), CondExpr);
+  }
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info. 
+  return ReplacingStmt;
+}
+
+Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
+  Stmt *ReplacingStmt = SynthMessageExpr(Exp);
+  
+  // Now do the actual rewrite.
+  ReplaceStmt(Exp, ReplacingStmt);
+  
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info. 
+  return ReplacingStmt;
+}
+
+// typedef struct objc_object Protocol;
+QualType RewriteObjC::getProtocolType() {
+  if (!ProtocolTypeDecl) {
+    ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
+                                           SourceLocation(), 
+                                           &Context->Idents.get("Protocol"),
+                                           Context->getObjCIdType());
+  }
+  return Context->getTypeDeclType(ProtocolTypeDecl);
+}
+
+/// RewriteObjCProtocolExpr - Rewrite a protocol expression into
+/// a synthesized/forward data reference (to the protocol's metadata).
+/// The forward references (and metadata) are generated in
+/// RewriteObjC::HandleTranslationUnit().
+Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
+  std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
+  IdentifierInfo *ID = &Context->Idents.get(Name);
+  VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 
+                          ID, QualType()/*UNUSED*/, VarDecl::Extern);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation());
+  Expr *DerefExpr = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
+                             Context->getPointerType(DRE->getType()),
+                             SourceLocation());
+  CastExpr *castExpr = new (Context) CStyleCastExpr(DerefExpr->getType(), DerefExpr, 
+                                          DerefExpr->getType(), 
+                                          SourceLocation(), SourceLocation());
+  ReplaceStmt(Exp, castExpr);
+  ProtocolExprDecls.insert(Exp->getProtocol());
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info. 
+  return castExpr;
+  
+}
+
+bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf, 
+                                             const char *endBuf) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '#') {
+      // Skip whitespace.
+      for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf)
+        ;
+      if (!strncmp(startBuf, "if", strlen("if")) ||
+          !strncmp(startBuf, "ifdef", strlen("ifdef")) ||
+          !strncmp(startBuf, "ifndef", strlen("ifndef")) ||
+          !strncmp(startBuf, "define", strlen("define")) ||
+          !strncmp(startBuf, "undef", strlen("undef")) ||
+          !strncmp(startBuf, "else", strlen("else")) ||
+          !strncmp(startBuf, "elif", strlen("elif")) ||
+          !strncmp(startBuf, "endif", strlen("endif")) ||
+          !strncmp(startBuf, "pragma", strlen("pragma")) ||
+          !strncmp(startBuf, "include", strlen("include")) ||
+          !strncmp(startBuf, "import", strlen("import")) ||
+          !strncmp(startBuf, "include_next", strlen("include_next")))
+        return true;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+/// SynthesizeObjCInternalStruct - Rewrite one internal struct corresponding to
+/// an objective-c class with ivars.
+void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                               std::string &Result) {
+  assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
+  assert(CDecl->getNameAsCString() && 
+         "Name missing in SynthesizeObjCInternalStruct");
+  // Do not synthesize more than once.
+  if (ObjCSynthesizedStructs.count(CDecl))
+    return;
+  ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
+  int NumIvars = CDecl->ivar_size();
+  SourceLocation LocStart = CDecl->getLocStart();
+  SourceLocation LocEnd = CDecl->getLocEnd();
+  
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  
+  // If no ivars and no root or if its root, directly or indirectly,
+  // have no ivars (thus not synthesized) then no need to synthesize this class.
+  if ((CDecl->isForwardDecl() || NumIvars == 0) &&
+      (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
+    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+    ReplaceText(LocStart, endBuf-startBuf, Result.c_str(), Result.size());
+    return;
+  }
+  
+  // FIXME: This has potential of causing problem. If 
+  // SynthesizeObjCInternalStruct is ever called recursively.
+  Result += "\nstruct ";
+  Result += CDecl->getNameAsString();
+  if (LangOpts.Microsoft)
+    Result += "_IMPL";
+
+  if (NumIvars > 0) {
+    const char *cursor = strchr(startBuf, '{');
+    assert((cursor && endBuf) 
+           && "SynthesizeObjCInternalStruct - malformed @interface");
+    // If the buffer contains preprocessor directives, we do more fine-grained
+    // rewrites. This is intended to fix code that looks like (which occurs in
+    // NSURL.h, for example):
+    //
+    // #ifdef XYZ
+    // @interface Foo : NSObject
+    // #else
+    // @interface FooBar : NSObject
+    // #endif
+    // {
+    //    int i;
+    // }
+    // @end
+    //
+    // This clause is segregated to avoid breaking the common case.
+    if (BufferContainsPPDirectives(startBuf, cursor)) {
+      SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() : 
+                                  CDecl->getClassLoc();
+      const char *endHeader = SM->getCharacterData(L);
+      endHeader += Lexer::MeasureTokenLength(L, *SM, LangOpts);
+
+      if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+        // advance to the end of the referenced protocols.
+        while (endHeader < cursor && *endHeader != '>') endHeader++;
+        endHeader++;
+      }
+      // rewrite the original header
+      ReplaceText(LocStart, endHeader-startBuf, Result.c_str(), Result.size());
+    } else {
+      // rewrite the original header *without* disturbing the '{'
+      ReplaceText(LocStart, cursor-startBuf-1, Result.c_str(), Result.size());
+    }
+    if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
+      Result = "\n    struct ";
+      Result += RCDecl->getNameAsString();
+      Result += "_IMPL ";
+      Result += RCDecl->getNameAsString();
+      Result += "_IVARS;\n";
+      
+      // insert the super class structure definition.
+      SourceLocation OnePastCurly =
+        LocStart.getFileLocWithOffset(cursor-startBuf+1);
+      InsertText(OnePastCurly, Result.c_str(), Result.size());
+    }
+    cursor++; // past '{'
+    
+    // Now comment out any visibility specifiers.
+    while (cursor < endBuf) {
+      if (*cursor == '@') {
+        SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
+        // Skip whitespace.
+        for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor)
+          /*scan*/;
+
+        // FIXME: presence of @public, etc. inside comment results in
+        // this transformation as well, which is still correct c-code.
+        if (!strncmp(cursor, "public", strlen("public")) ||
+            !strncmp(cursor, "private", strlen("private")) ||
+            !strncmp(cursor, "package", strlen("package")) ||
+            !strncmp(cursor, "protected", strlen("protected")))
+          InsertText(atLoc, "// ", 3);
+      }
+      // FIXME: If there are cases where '<' is used in ivar declaration part
+      // of user code, then scan the ivar list and use needToScanForQualifiers
+      // for type checking.
+      else if (*cursor == '<') {
+        SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
+        InsertText(atLoc, "/* ", 3);
+        cursor = strchr(cursor, '>');
+        cursor++;
+        atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
+        InsertText(atLoc, " */", 3);
+      } else if (*cursor == '^') { // rewrite block specifier.
+        SourceLocation caretLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
+        ReplaceText(caretLoc, 1, "*", 1);
+      }
+      cursor++;
+    }
+    // Don't forget to add a ';'!!
+    InsertText(LocEnd.getFileLocWithOffset(1), ";", 1);
+  } else { // we don't have any instance variables - insert super struct.
+    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+    Result += " {\n    struct ";
+    Result += RCDecl->getNameAsString();
+    Result += "_IMPL ";
+    Result += RCDecl->getNameAsString();
+    Result += "_IVARS;\n};\n";
+    ReplaceText(LocStart, endBuf-startBuf, Result.c_str(), Result.size());
+  }
+  // Mark this struct as having been generated.
+  if (!ObjCSynthesizedStructs.insert(CDecl))
+    assert(false && "struct already synthesize- SynthesizeObjCInternalStruct");
+}
+
+// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
+/// class methods.
+template<typename MethodIterator>
+void RewriteObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                             MethodIterator MethodEnd,
+                                             bool IsInstanceMethod,
+                                             const char *prefix,
+                                             const char *ClassName,
+                                             std::string &Result) {
+  if (MethodBegin == MethodEnd) return;
+  
+  static bool objc_impl_method = false;
+  if (!objc_impl_method) {
+    /* struct _objc_method {
+       SEL _cmd;
+       char *method_types;
+       void *_imp;
+       }
+     */
+    Result += "\nstruct _objc_method {\n";
+    Result += "\tSEL _cmd;\n";
+    Result += "\tchar *method_types;\n";
+    Result += "\tvoid *_imp;\n";
+    Result += "};\n";
+    
+    objc_impl_method = true;
+  }
+  
+  // Build _objc_method_list for class's methods if needed
+  
+  /* struct  {
+   struct _objc_method_list *next_method;
+   int method_count;
+   struct _objc_method method_list[];
+   }
+   */
+  unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
+  Result += "\nstatic struct {\n";
+  Result += "\tstruct _objc_method_list *next_method;\n";
+  Result += "\tint method_count;\n";
+  Result += "\tstruct _objc_method method_list[";
+  Result += utostr(NumMethods);
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
+  Result += "_METHODS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __";
+  Result += IsInstanceMethod ? "inst" : "cls";
+  Result += "_meth\")))= ";
+  Result += "{\n\t0, " + utostr(NumMethods) + "\n";
+
+  Result += "\t,{{(SEL)\"";
+  Result += (*MethodBegin)->getSelector().getAsString().c_str();
+  std::string MethodTypeString;
+  Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+  Result += "\", \"";
+  Result += MethodTypeString;
+  Result += "\", (void *)";
+  Result += MethodInternalNames[*MethodBegin];
+  Result += "}\n";
+  for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
+    Result += "\t  ,{(SEL)\"";
+    Result += (*MethodBegin)->getSelector().getAsString().c_str();
+    std::string MethodTypeString;
+    Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+    Result += "\", \"";
+    Result += MethodTypeString;
+    Result += "\", (void *)";
+    Result += MethodInternalNames[*MethodBegin];
+    Result += "}\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
+void RewriteObjC::
+RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
+                            const char *ClassName, std::string &Result) {
+  static bool objc_protocol_methods = false;
+
+  // Output struct protocol_methods holder of method selector and type.
+  if (!objc_protocol_methods && !PDecl->isForwardDecl()) {
+    /* struct protocol_methods {
+     SEL _cmd;
+     char *method_types;
+     }
+     */
+    Result += "\nstruct _protocol_methods {\n";
+    Result += "\tstruct objc_selector *_cmd;\n";
+    Result += "\tchar *method_types;\n";
+    Result += "};\n";
+    
+    objc_protocol_methods = true;
+  }
+  // Do not synthesize the protocol more than once.
+  if (ObjCSynthesizedProtocols.count(PDecl))
+    return;
+         
+    if (PDecl->instmeth_begin(*Context) != PDecl->instmeth_end(*Context)) {
+      unsigned NumMethods = std::distance(PDecl->instmeth_begin(*Context),
+                                          PDecl->instmeth_end(*Context));
+    /* struct _objc_protocol_method_list {
+     int protocol_method_count;
+     struct protocol_methods protocols[];
+     }
+     */
+    Result += "\nstatic struct {\n";
+    Result += "\tint protocol_method_count;\n";
+    Result += "\tstruct _protocol_methods protocol_methods[";
+    Result += utostr(NumMethods);
+    Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
+      "{\n\t" + utostr(NumMethods) + "\n";
+    
+    // Output instance methods declared in this protocol.
+    for (ObjCProtocolDecl::instmeth_iterator 
+           I = PDecl->instmeth_begin(*Context), 
+           E = PDecl->instmeth_end(*Context); 
+         I != E; ++I) {
+      if (I == PDecl->instmeth_begin(*Context))
+        Result += "\t  ,{{(struct objc_selector *)\"";
+      else
+        Result += "\t  ,{(struct objc_selector *)\"";
+      Result += (*I)->getSelector().getAsString().c_str();
+      std::string MethodTypeString;
+      Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
+      Result += "\", \"";
+      Result += MethodTypeString;
+      Result += "\"}\n";
+    }
+    Result += "\t }\n};\n";
+  }
+  
+  // Output class methods declared in this protocol.
+  unsigned NumMethods = std::distance(PDecl->classmeth_begin(*Context),
+                                      PDecl->classmeth_end(*Context));
+  if (NumMethods > 0) {
+    /* struct _objc_protocol_method_list {
+     int protocol_method_count;
+     struct protocol_methods protocols[];
+     }
+     */
+    Result += "\nstatic struct {\n";
+    Result += "\tint protocol_method_count;\n";
+    Result += "\tstruct _protocol_methods protocol_methods[";
+    Result += utostr(NumMethods);
+    Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
+           "{\n\t";
+    Result += utostr(NumMethods);
+    Result += "\n";
+    
+    // Output instance methods declared in this protocol.
+    for (ObjCProtocolDecl::classmeth_iterator 
+           I = PDecl->classmeth_begin(*Context), 
+           E = PDecl->classmeth_end(*Context);
+         I != E; ++I) {
+      if (I == PDecl->classmeth_begin(*Context))
+        Result += "\t  ,{{(struct objc_selector *)\"";
+      else
+        Result += "\t  ,{(struct objc_selector *)\"";
+      Result += (*I)->getSelector().getAsString().c_str();
+      std::string MethodTypeString;
+      Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
+      Result += "\", \"";
+      Result += MethodTypeString;
+      Result += "\"}\n";
+    }
+    Result += "\t }\n};\n";
+  }
+
+  // Output:
+  /* struct _objc_protocol {
+   // Objective-C 1.0 extensions
+   struct _objc_protocol_extension *isa;
+   char *protocol_name;
+   struct _objc_protocol **protocol_list;
+   struct _objc_protocol_method_list *instance_methods;
+   struct _objc_protocol_method_list *class_methods;
+   };  
+   */
+  static bool objc_protocol = false;
+  if (!objc_protocol) {
+    Result += "\nstruct _objc_protocol {\n";
+    Result += "\tstruct _objc_protocol_extension *isa;\n";
+    Result += "\tchar *protocol_name;\n";
+    Result += "\tstruct _objc_protocol **protocol_list;\n";
+    Result += "\tstruct _objc_protocol_method_list *instance_methods;\n";
+    Result += "\tstruct _objc_protocol_method_list *class_methods;\n";
+    Result += "};\n";
+    
+    objc_protocol = true;
+  }
+  
+  Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
+  Result += PDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
+    "{\n\t0, \"";
+  Result += PDecl->getNameAsString();
+  Result += "\", 0, ";
+  if (PDecl->instmeth_begin(*Context) != PDecl->instmeth_end(*Context)) {
+    Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += ", ";
+  }
+  else
+    Result += "0, ";
+  if (PDecl->classmeth_begin(*Context) != PDecl->classmeth_end(*Context)) {
+    Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += "\n";
+  }
+  else
+    Result += "0\n";
+  Result += "};\n";
+  
+  // Mark this protocol as having been generated.
+  if (!ObjCSynthesizedProtocols.insert(PDecl))
+    assert(false && "protocol already synthesized");
+
+}
+
+void RewriteObjC::
+RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Protocols,
+                                const char *prefix, const char *ClassName,
+                                std::string &Result) {
+  if (Protocols.empty()) return;
+  
+  for (unsigned i = 0; i != Protocols.size(); i++)
+    RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result);
+
+  // Output the top lovel protocol meta-data for the class.
+  /* struct _objc_protocol_list {
+   struct _objc_protocol_list *next;
+   int    protocol_count;
+   struct _objc_protocol *class_protocols[];
+   }
+   */
+  Result += "\nstatic struct {\n";
+  Result += "\tstruct _objc_protocol_list *next;\n";
+  Result += "\tint    protocol_count;\n";
+  Result += "\tstruct _objc_protocol *class_protocols[";
+  Result += utostr(Protocols.size());
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += "_PROTOCOLS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
+    "{\n\t0, ";
+  Result += utostr(Protocols.size());
+  Result += "\n";
+  
+  Result += "\t,{&_OBJC_PROTOCOL_";
+  Result += Protocols[0]->getNameAsString();
+  Result += " \n";
+  
+  for (unsigned i = 1; i != Protocols.size(); i++) {
+    Result += "\t ,&_OBJC_PROTOCOL_";
+    Result += Protocols[i]->getNameAsString();
+    Result += "\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+
+/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category 
+/// implementation.
+void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
+                                              std::string &Result) {
+  ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
+  // Find category declaration for this implementation.
+  ObjCCategoryDecl *CDecl;
+  for (CDecl = ClassDecl->getCategoryList(); CDecl; 
+       CDecl = CDecl->getNextClassCategory())
+    if (CDecl->getIdentifier() == IDecl->getIdentifier())
+      break;
+  
+  std::string FullCategoryName = ClassDecl->getNameAsString();
+  FullCategoryName += '_';
+  FullCategoryName += IDecl->getNameAsString();
+    
+  // Build _objc_method_list for class's instance methods if needed
+  llvm::SmallVector<ObjCMethodDecl *, 32> 
+    InstanceMethods(IDecl->instmeth_begin(*Context),
+                    IDecl->instmeth_end(*Context));
+
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(*Context),
+         PropEnd = IDecl->propimpl_end(*Context);
+       Prop != PropEnd; ++Prop) {
+    if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!(*Prop)->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      InstanceMethods.push_back(Setter);
+  }
+  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
+                             true, "CATEGORY_", FullCategoryName.c_str(),
+                             Result);
+  
+  // Build _objc_method_list for class's class methods if needed
+  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(*Context),
+                             IDecl->classmeth_end(*Context),
+                             false, "CATEGORY_", FullCategoryName.c_str(),
+                             Result);
+  
+  // Protocols referenced in class declaration?
+  // Null CDecl is case of a category implementation with no category interface
+  if (CDecl)
+    RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY",
+                                    FullCategoryName.c_str(), Result);
+  /* struct _objc_category {
+   char *category_name;
+   char *class_name;
+   struct _objc_method_list *instance_methods;
+   struct _objc_method_list *class_methods;
+   struct _objc_protocol_list *protocols;
+   // Objective-C 1.0 extensions
+   uint32_t size;     // sizeof (struct _objc_category)
+   struct _objc_property_list *instance_properties;  // category's own 
+                                                     // @property decl.
+   };   
+   */
+  
+  static bool objc_category = false;
+  if (!objc_category) {
+    Result += "\nstruct _objc_category {\n";
+    Result += "\tchar *category_name;\n";
+    Result += "\tchar *class_name;\n";
+    Result += "\tstruct _objc_method_list *instance_methods;\n";
+    Result += "\tstruct _objc_method_list *class_methods;\n";
+    Result += "\tstruct _objc_protocol_list *protocols;\n";
+    Result += "\tunsigned int size;\n";   
+    Result += "\tstruct _objc_property_list *instance_properties;\n";
+    Result += "};\n";
+    objc_category = true;
+  }
+  Result += "\nstatic struct _objc_category _OBJC_CATEGORY_";
+  Result += FullCategoryName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
+  Result += IDecl->getNameAsString();
+  Result += "\"\n\t, \"";
+  Result += ClassDecl->getNameAsString();
+  Result += "\"\n";
+  
+  if (IDecl->instmeth_begin(*Context) != IDecl->instmeth_end(*Context)) {
+    Result += "\t, (struct _objc_method_list *)"
+           "&_OBJC_CATEGORY_INSTANCE_METHODS_";
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+  if (IDecl->classmeth_begin(*Context) != IDecl->classmeth_end(*Context)) {
+    Result += "\t, (struct _objc_method_list *)"
+           "&_OBJC_CATEGORY_CLASS_METHODS_";
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+  
+  if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_"; 
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+  Result += "\t, sizeof(struct _objc_category), 0\n};\n";
+}
+
+/// SynthesizeIvarOffsetComputation - This rutine synthesizes computation of
+/// ivar offset.
+void RewriteObjC::SynthesizeIvarOffsetComputation(ObjCImplementationDecl *IDecl, 
+                                                  ObjCIvarDecl *ivar, 
+                                                  std::string &Result) {
+  if (ivar->isBitField()) {
+    // FIXME: The hack below doesn't work for bitfields. For now, we simply
+    // place all bitfields at offset 0.
+    Result += "0";
+  } else {
+    Result += "__OFFSETOFIVAR__(struct ";
+    Result += IDecl->getNameAsString();
+    if (LangOpts.Microsoft)
+      Result += "_IMPL";
+    Result += ", ";
+    Result += ivar->getNameAsString();
+    Result += ")";
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Meta Data Emission
+//===----------------------------------------------------------------------===//
+
+void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                           std::string &Result) {
+  ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
+  
+  // Explictly declared @interface's are already synthesized.
+  if (CDecl->isImplicitInterfaceDecl()) {
+    // FIXME: Implementation of a class with no @interface (legacy) doese not 
+    // produce correct synthesis as yet.
+    SynthesizeObjCInternalStruct(CDecl, Result);
+  }
+  
+  // Build _objc_ivar_list metadata for classes ivars if needed
+  unsigned NumIvars = !IDecl->ivar_empty(*Context)
+                      ? IDecl->ivar_size(*Context) 
+                      : (CDecl ? CDecl->ivar_size() : 0);
+  if (NumIvars > 0) {
+    static bool objc_ivar = false;
+    if (!objc_ivar) {
+      /* struct _objc_ivar {
+          char *ivar_name;
+          char *ivar_type;
+          int ivar_offset;
+        };  
+       */
+      Result += "\nstruct _objc_ivar {\n";
+      Result += "\tchar *ivar_name;\n";
+      Result += "\tchar *ivar_type;\n";
+      Result += "\tint ivar_offset;\n";
+      Result += "};\n";
+      
+      objc_ivar = true;
+    }
+
+    /* struct {
+       int ivar_count;
+       struct _objc_ivar ivar_list[nIvars];
+       };  
+     */
+    Result += "\nstatic struct {\n"; 
+    Result += "\tint ivar_count;\n";
+    Result += "\tstruct _objc_ivar ivar_list[";
+    Result += utostr(NumIvars);
+    Result += "];\n} _OBJC_INSTANCE_VARIABLES_";
+    Result += IDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
+      "{\n\t";
+    Result += utostr(NumIvars);
+    Result += "\n";
+    
+    ObjCInterfaceDecl::ivar_iterator IVI, IVE;
+    llvm::SmallVector<ObjCIvarDecl *, 8> IVars;
+    if (!IDecl->ivar_empty(*Context)) {
+      for (ObjCImplementationDecl::ivar_iterator 
+             IV = IDecl->ivar_begin(*Context),
+             IVEnd = IDecl->ivar_end(*Context);
+           IV != IVEnd; ++IV)
+        IVars.push_back(*IV);
+      IVI = IVars.begin();
+      IVE = IVars.end();
+    } else {
+      IVI = CDecl->ivar_begin();
+      IVE = CDecl->ivar_end();
+    }
+    Result += "\t,{{\"";
+    Result += (*IVI)->getNameAsString();
+    Result += "\", \"";
+    std::string TmpString, StrEncoding;
+    Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI);
+    QuoteDoublequotes(TmpString, StrEncoding);
+    Result += StrEncoding;
+    Result += "\", ";
+    SynthesizeIvarOffsetComputation(IDecl, *IVI, Result);
+    Result += "}\n";
+    for (++IVI; IVI != IVE; ++IVI) {
+      Result += "\t  ,{\"";
+      Result += (*IVI)->getNameAsString();
+      Result += "\", \"";
+      std::string TmpString, StrEncoding;
+      Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI);
+      QuoteDoublequotes(TmpString, StrEncoding);
+      Result += StrEncoding;
+      Result += "\", ";
+      SynthesizeIvarOffsetComputation(IDecl, (*IVI), Result);
+      Result += "}\n";
+    }
+    
+    Result += "\t }\n};\n";
+  }
+  
+  // Build _objc_method_list for class's instance methods if needed
+  llvm::SmallVector<ObjCMethodDecl *, 32> 
+    InstanceMethods(IDecl->instmeth_begin(*Context),
+                    IDecl->instmeth_end(*Context));
+
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(*Context),
+         PropEnd = IDecl->propimpl_end(*Context);
+       Prop != PropEnd; ++Prop) {
+    if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!(*Prop)->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      InstanceMethods.push_back(Setter);
+  }
+  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
+                             true, "", IDecl->getNameAsCString(), Result);
+  
+  // Build _objc_method_list for class's class methods if needed
+  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(*Context), 
+                             IDecl->classmeth_end(*Context),
+                             false, "", IDecl->getNameAsCString(), Result);
+    
+  // Protocols referenced in class declaration?
+  RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(),
+                                  "CLASS", CDecl->getNameAsCString(), Result);
+    
+  // Declaration of class/meta-class metadata
+  /* struct _objc_class {
+   struct _objc_class *isa; // or const char *root_class_name when metadata
+   const char *super_class_name;
+   char *name;
+   long version;
+   long info;
+   long instance_size;
+   struct _objc_ivar_list *ivars;
+   struct _objc_method_list *methods;
+   struct objc_cache *cache;
+   struct objc_protocol_list *protocols;
+   const char *ivar_layout;
+   struct _objc_class_ext  *ext;
+   };  
+  */
+  static bool objc_class = false;
+  if (!objc_class) {
+    Result += "\nstruct _objc_class {\n";
+    Result += "\tstruct _objc_class *isa;\n";
+    Result += "\tconst char *super_class_name;\n";
+    Result += "\tchar *name;\n";
+    Result += "\tlong version;\n";
+    Result += "\tlong info;\n";
+    Result += "\tlong instance_size;\n";
+    Result += "\tstruct _objc_ivar_list *ivars;\n";
+    Result += "\tstruct _objc_method_list *methods;\n";
+    Result += "\tstruct objc_cache *cache;\n";
+    Result += "\tstruct _objc_protocol_list *protocols;\n";
+    Result += "\tconst char *ivar_layout;\n";
+    Result += "\tstruct _objc_class_ext  *ext;\n";
+    Result += "};\n";
+    objc_class = true;
+  }
+  
+  // Meta-class metadata generation.
+  ObjCInterfaceDecl *RootClass = 0;
+  ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
+  while (SuperClass) {
+    RootClass = SuperClass;
+    SuperClass = SuperClass->getSuperClass();
+  }
+  SuperClass = CDecl->getSuperClass();
+  
+  Result += "\nstatic struct _objc_class _OBJC_METACLASS_";
+  Result += CDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
+  "{\n\t(struct _objc_class *)\"";
+  Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString());
+  Result += "\"";
+
+  if (SuperClass) {
+    Result += ", \"";
+    Result += SuperClass->getNameAsString();
+    Result += "\", \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  else {
+    Result += ", 0, \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
+  // 'info' field is initialized to CLS_META(2) for metaclass
+  Result += ", 0,2, sizeof(struct _objc_class), 0";
+  if (IDecl->classmeth_begin(*Context) != IDecl->classmeth_end(*Context)) {
+    Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
+    Result += IDecl->getNameAsString();
+    Result += "\n"; 
+  }
+  else
+    Result += ", 0\n";
+  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
+    Result += CDecl->getNameAsString();
+    Result += ",0,0\n";
+  }
+  else
+    Result += "\t,0,0,0,0\n";
+  Result += "};\n";
+  
+  // class metadata generation.
+  Result += "\nstatic struct _objc_class _OBJC_CLASS_";
+  Result += CDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= "
+            "{\n\t&_OBJC_METACLASS_";
+  Result += CDecl->getNameAsString();
+  if (SuperClass) {
+    Result += ", \"";
+    Result += SuperClass->getNameAsString();
+    Result += "\", \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  else {
+    Result += ", 0, \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  // 'info' field is initialized to CLS_CLASS(1) for class
+  Result += ", 0,1";
+  if (!ObjCSynthesizedStructs.count(CDecl))
+    Result += ",0";
+  else {
+    // class has size. Must synthesize its size.
+    Result += ",sizeof(struct ";
+    Result += CDecl->getNameAsString();
+    if (LangOpts.Microsoft)
+      Result += "_IMPL";
+    Result += ")";
+  }
+  if (NumIvars > 0) {
+    Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
+    Result += CDecl->getNameAsString();
+    Result += "\n\t";
+  }
+  else
+    Result += ",0";
+  if (IDecl->instmeth_begin(*Context) != IDecl->instmeth_end(*Context)) {
+    Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
+    Result += CDecl->getNameAsString();
+    Result += ", 0\n\t"; 
+  }
+  else
+    Result += ",0,0";
+  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
+    Result += CDecl->getNameAsString();
+    Result += ", 0,0\n";
+  }
+  else
+    Result += ",0,0,0\n";
+  Result += "};\n";
+}
+
+/// RewriteImplementations - This routine rewrites all method implementations
+/// and emits meta-data.
+
+void RewriteObjC::RewriteImplementations() {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+  
+  // Rewrite implemented methods
+  for (int i = 0; i < ClsDefCount; i++)
+    RewriteImplementationDecl(ClassImplementation[i]);
+  
+  for (int i = 0; i < CatDefCount; i++)
+    RewriteImplementationDecl(CategoryImplementation[i]);
+}
+  
+void RewriteObjC::SynthesizeMetaDataIntoBuffer(std::string &Result) {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+
+  // This is needed for determining instance variable offsets.
+  Result += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)\n";   
+  // For each implemented class, write out all its meta data.
+  for (int i = 0; i < ClsDefCount; i++)
+    RewriteObjCClassMetaData(ClassImplementation[i], Result);
+  
+  // For each implemented category, write out all its meta data.
+  for (int i = 0; i < CatDefCount; i++)
+    RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
+
+  // Write objc_symtab metadata
+  /*
+   struct _objc_symtab
+   {
+   long sel_ref_cnt;
+   SEL *refs;
+   short cls_def_cnt;
+   short cat_def_cnt;
+   void *defs[cls_def_cnt + cat_def_cnt];
+   }; 
+   */
+  
+  Result += "\nstruct _objc_symtab {\n";
+  Result += "\tlong sel_ref_cnt;\n";
+  Result += "\tSEL *refs;\n";
+  Result += "\tshort cls_def_cnt;\n";
+  Result += "\tshort cat_def_cnt;\n";
+  Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n";
+  Result += "};\n\n";
+  
+  Result += "static struct _objc_symtab "
+         "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n";
+  Result += "\t0, 0, " + utostr(ClsDefCount) 
+            + ", " + utostr(CatDefCount) + "\n";
+  for (int i = 0; i < ClsDefCount; i++) {
+    Result += "\t,&_OBJC_CLASS_";
+    Result += ClassImplementation[i]->getNameAsString();
+    Result += "\n";
+  }
+  
+  for (int i = 0; i < CatDefCount; i++) {
+    Result += "\t,&_OBJC_CATEGORY_";
+    Result += CategoryImplementation[i]->getClassInterface()->getNameAsString();
+    Result += "_";
+    Result += CategoryImplementation[i]->getNameAsString();
+    Result += "\n";
+  }
+  
+  Result += "};\n\n";
+  
+  // Write objc_module metadata
+  
+  /*
+   struct _objc_module {
+    long version;
+    long size;
+    const char *name;
+    struct _objc_symtab *symtab;
+   }
+  */
+  
+  Result += "\nstruct _objc_module {\n";
+  Result += "\tlong version;\n";
+  Result += "\tlong size;\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tstruct _objc_symtab *symtab;\n";
+  Result += "};\n\n";
+  Result += "static struct _objc_module "
+    "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n";
+  Result += "\t" + utostr(OBJC_ABI_VERSION) + 
+  ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
+  Result += "};\n\n";
+
+  if (LangOpts.Microsoft) {
+    if (ProtocolExprDecls.size()) {
+      Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n";
+      Result += "#pragma data_seg(push, \".objc_protocol$B\")\n";
+      for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(), 
+           E = ProtocolExprDecls.end(); I != E; ++I) {
+        Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_";
+        Result += (*I)->getNameAsString();
+        Result += " = &_OBJC_PROTOCOL_";
+        Result += (*I)->getNameAsString();
+        Result += ";\n";
+      }
+      Result += "#pragma data_seg(pop)\n\n";
+    }
+    Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n";
+    Result += "#pragma data_seg(push, \".objc_module_info$B\")\n";
+    Result += "static struct _objc_module *_POINTER_OBJC_MODULES = ";
+    Result += "&_OBJC_MODULES;\n";
+    Result += "#pragma data_seg(pop)\n\n";
+  }
+}
+
+std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                                   const char *funcName,
+                                                   std::string Tag) {
+  const FunctionType *AFT = CE->getFunctionType();
+  QualType RT = AFT->getResultType();
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static " + RT.getAsString() + " __" +
+                  funcName + "_" + "block_func_" + utostr(i);
+
+  BlockDecl *BD = CE->getBlockDecl();
+  
+  if (isa<FunctionNoProtoType>(AFT)) {
+    // No user-supplied arguments. Still need to pass in a pointer to the 
+    // block (to reference imported block decl refs).
+    S += "(" + StructRef + " *__cself)";
+  } else if (BD->param_empty()) {
+    S += "(" + StructRef + " *__cself)";
+  } else {
+    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
+    assert(FT && "SynthesizeBlockFunc: No function proto");
+    S += '(';
+    // first add the implicit argument.
+    S += StructRef + " *__cself, ";
+    std::string ParamStr;
+    for (BlockDecl::param_iterator AI = BD->param_begin(),
+         E = BD->param_end(); AI != E; ++AI) {
+      if (AI != BD->param_begin()) S += ", ";
+      ParamStr = (*AI)->getNameAsString();
+      (*AI)->getType().getAsStringInternal(ParamStr);
+      S += ParamStr;
+    }
+    if (FT->isVariadic()) {
+      if (!BD->param_empty()) S += ", ";
+      S += "...";
+    }
+    S += ')';
+  }
+  S += " {\n";
+  
+  // Create local declarations to avoid rewriting all closure decl ref exprs.
+  // First, emit a declaration for all "by ref" decls.
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 
+       E = BlockByRefDecls.end(); I != E; ++I) {
+    S += "  ";
+    std::string Name = (*I)->getNameAsString();
+    Context->getPointerType((*I)->getType()).getAsStringInternal(Name);
+    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
+  }    
+  // Next, emit a declaration for all "by copy" declarations.
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 
+       E = BlockByCopyDecls.end(); I != E; ++I) {
+    S += "  ";
+    std::string Name = (*I)->getNameAsString();
+    // Handle nested closure invocation. For example:
+    //
+    //   void (^myImportedClosure)(void);
+    //   myImportedClosure  = ^(void) { setGlobalInt(x + y); };
+    // 
+    //   void (^anotherClosure)(void);
+    //   anotherClosure = ^(void) {
+    //     myImportedClosure(); // import and invoke the closure
+    //   };
+    //
+    if (isTopLevelBlockPointerType((*I)->getType()))
+      S += "struct __block_impl *";
+    else
+      (*I)->getType().getAsStringInternal(Name);
+    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
+  }
+  std::string RewrittenStr = RewrittenBlockExprs[CE];
+  const char *cstr = RewrittenStr.c_str();
+  while (*cstr++ != '{') ;
+  S += cstr;
+  S += "\n";
+  return S;
+}
+
+std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                                   const char *funcName,
+                                                   std::string Tag) {
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static void __";
+  
+  S += funcName;
+  S += "_block_copy_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*dst, " + StructRef;
+  S += "*src) {";
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 
+      E = ImportedBlockDecls.end(); I != E; ++I) {
+    S += "_Block_object_assign((void*)&dst->";
+    S += (*I)->getNameAsString();
+    S += ", (void*)src->";
+    S += (*I)->getNameAsString();
+    S += ", 3/*BLOCK_FIELD_IS_OBJECT*/);}";
+  }
+  S += "\nstatic void __";
+  S += funcName;
+  S += "_block_dispose_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*src) {";
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 
+      E = ImportedBlockDecls.end(); I != E; ++I) {
+    S += "_Block_object_dispose((void*)src->";
+    S += (*I)->getNameAsString();
+    S += ", 3/*BLOCK_FIELD_IS_OBJECT*/);";
+  }
+  S += "}\n";  
+  return S;
+}
+
+std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
+                                               bool hasCopyDisposeHelpers) {
+  std::string S = "\nstruct " + Tag;
+  std::string Constructor = "  " + Tag;
+  
+  S += " {\n  struct __block_impl impl;\n";
+  
+  if (hasCopyDisposeHelpers)
+    S += "  void *copy;\n  void *dispose;\n";
+    
+  Constructor += "(void *fp";
+  
+  if (hasCopyDisposeHelpers)
+    Constructor += ", void *copyHelp, void *disposeHelp";
+    
+  if (BlockDeclRefs.size()) {
+    // Output all "by copy" declarations.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      // Handle nested closure invocation. For example:
+      //
+      //   void (^myImportedBlock)(void);
+      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
+      // 
+      //   void (^anotherBlock)(void);
+      //   anotherBlock = ^(void) {
+      //     myImportedBlock(); // import and invoke the closure
+      //   };
+      //
+      if (isTopLevelBlockPointerType((*I)->getType())) {
+        S += "struct __block_impl *";
+        Constructor += ", void *" + ArgName;
+      } else {
+        (*I)->getType().getAsStringInternal(FieldName);
+        (*I)->getType().getAsStringInternal(ArgName);
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + ";\n";
+    }
+    // Output all "by ref" declarations.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      // Handle nested closure invocation. For example:
+      //
+      //   void (^myImportedBlock)(void);
+      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
+      // 
+      //   void (^anotherBlock)(void);
+      //   anotherBlock = ^(void) {
+      //     myImportedBlock(); // import and invoke the closure
+      //   };
+      //
+      if (isTopLevelBlockPointerType((*I)->getType())) {
+        S += "struct __block_impl *";
+        Constructor += ", void *" + ArgName;
+      } else {
+        Context->getPointerType((*I)->getType()).getAsStringInternal(FieldName);
+        Context->getPointerType((*I)->getType()).getAsStringInternal(ArgName);
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + "; // by ref\n";
+    }
+    // Finish writing the constructor.
+    Constructor += ", int flags=0) {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Size = sizeof(";
+    Constructor += Tag + ");\n    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+    
+    if (hasCopyDisposeHelpers)
+      Constructor += "    copy = copyHelp;\n    dispose = disposeHelp;\n";
+      
+    // Initialize all "by copy" arguments.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+      Constructor += "    ";
+      if (isTopLevelBlockPointerType((*I)->getType()))
+        Constructor += Name + " = (struct __block_impl *)_";
+      else
+        Constructor += Name + " = _";
+      Constructor += Name + ";\n";
+    }
+    // Initialize all "by ref" arguments.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+      Constructor += "    ";
+      if (isTopLevelBlockPointerType((*I)->getType()))
+        Constructor += Name + " = (struct __block_impl *)_";
+      else
+        Constructor += Name + " = _";
+      Constructor += Name + ";\n";
+    }
+  } else {
+    // Finish writing the constructor.
+    Constructor += ", int flags=0) {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Size = sizeof(";
+    Constructor += Tag + ");\n    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+    if (hasCopyDisposeHelpers)
+      Constructor += "    copy = copyHelp;\n    dispose = disposeHelp;\n";
+  }
+  Constructor += "  ";
+  Constructor += "}\n";
+  S += Constructor;
+  S += "};\n";
+  return S;
+}
+
+void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                                const char *FunName) {
+  // Insert closures that were part of the function.
+  for (unsigned i = 0; i < Blocks.size(); i++) {
+
+    CollectBlockDeclRefInfo(Blocks[i]);
+
+    std::string Tag = "__" + std::string(FunName) + "_block_impl_" + utostr(i);
+                      
+    std::string CI = SynthesizeBlockImpl(Blocks[i], Tag, 
+                                         ImportedBlockDecls.size() > 0);
+
+    InsertText(FunLocStart, CI.c_str(), CI.size());
+
+    std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, Tag);
+    
+    InsertText(FunLocStart, CF.c_str(), CF.size());
+
+    if (ImportedBlockDecls.size()) {
+      std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, Tag);
+      InsertText(FunLocStart, HF.c_str(), HF.size());
+    }
+    
+    BlockDeclRefs.clear();
+    BlockByRefDecls.clear();
+    BlockByCopyDecls.clear();
+    BlockCallExprs.clear();
+    ImportedBlockDecls.clear();
+  }
+  Blocks.clear();
+  RewrittenBlockExprs.clear();
+}
+
+void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
+  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
+  const char *FuncName = FD->getNameAsCString();
+  
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
+  //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
+  //SourceLocation FunLocStart = MD->getLocStart();
+  // FIXME: This hack works around a bug in Rewrite.InsertText().
+  SourceLocation FunLocStart = MD->getLocStart().getFileLocWithOffset(-1);
+  std::string FuncName = MD->getSelector().getAsString();
+  // Convert colons to underscores.
+  std::string::size_type loc = 0;
+  while ((loc = FuncName.find(":", loc)) != std::string::npos)
+    FuncName.replace(loc, 1, "_");
+  
+  SynthesizeBlockLiterals(FunLocStart, FuncName.c_str());
+}
+
+void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) {
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
+        GetBlockDeclRefExprs(CBE->getBody());
+      else
+        GetBlockDeclRefExprs(*CI);
+    }
+  // Handle specific things.
+  if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S))
+    // FIXME: Handle enums.
+    if (!isa<FunctionDecl>(CDRE->getDecl()))
+      BlockDeclRefs.push_back(CDRE);
+  return;
+}
+
+void RewriteObjC::GetBlockCallExprs(Stmt *S) {
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
+        GetBlockCallExprs(CBE->getBody());
+      else
+        GetBlockCallExprs(*CI);
+    }
+      
+  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
+    if (CE->getCallee()->getType()->isBlockPointerType()) {
+      BlockCallExprs[dyn_cast<BlockDeclRefExpr>(CE->getCallee())] = CE;
+    }
+  }
+  return;
+}
+
+Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp) {
+  // Navigate to relevant type information.
+  const char *closureName = 0;
+  const BlockPointerType *CPT = 0;
+  
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp->getCallee())) {
+    closureName = DRE->getDecl()->getNameAsCString();
+    CPT = DRE->getType()->getAsBlockPointerType();
+  } else if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(Exp->getCallee())) {
+    closureName = CDRE->getDecl()->getNameAsCString();
+    CPT = CDRE->getType()->getAsBlockPointerType();
+  } else if (MemberExpr *MExpr = dyn_cast<MemberExpr>(Exp->getCallee())) {
+    closureName = MExpr->getMemberDecl()->getNameAsCString();
+    CPT = MExpr->getType()->getAsBlockPointerType();
+  } else {
+    assert(1 && "RewriteBlockClass: Bad type");
+  }
+  assert(CPT && "RewriteBlockClass: Bad type");
+  const FunctionType *FT = CPT->getPointeeType()->getAsFunctionType();
+  assert(FT && "RewriteBlockClass: Bad type");
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+  
+  RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+                                      SourceLocation(),
+                                      &Context->Idents.get("__block_impl"));
+  QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
+
+  // Generate a funky cast.
+  llvm::SmallVector<QualType, 8> ArgTypes;
+    
+  // Push the block argument type.
+  ArgTypes.push_back(PtrBlock);
+  if (FTP) {
+    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 
+         E = FTP->arg_type_end(); I && (I != E); ++I) {
+      QualType t = *I;
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (isTopLevelBlockPointerType(t)) {
+        const BlockPointerType *BPT = t->getAsBlockPointerType();
+        t = Context->getPointerType(BPT->getPointeeType());
+      }
+      ArgTypes.push_back(t);
+    }
+  }
+  // Now do the pointer to function cast.
+  QualType PtrToFuncCastType = Context->getFunctionType(Exp->getType(), 
+    &ArgTypes[0], ArgTypes.size(), false/*no variadic*/, 0);
+    
+  PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
+  
+  CastExpr *BlkCast = new (Context) CStyleCastExpr(PtrBlock, Exp->getCallee(),
+                                                   PtrBlock, SourceLocation(),
+                                                   SourceLocation());
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                          BlkCast);
+  //PE->dump();
+  
+  FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
+                     &Context->Idents.get("FuncPtr"), Context->VoidPtrTy, 
+                                    /*BitWidth=*/0, /*Mutable=*/true);
+  MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
+                                            FD->getType());
+  
+  CastExpr *FunkCast = new (Context) CStyleCastExpr(PtrToFuncCastType, ME,
+                                                    PtrToFuncCastType,
+                                                    SourceLocation(),
+                                                    SourceLocation());
+  PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast);
+  
+  llvm::SmallVector<Expr*, 8> BlkExprs;
+  // Add the implicit argument.
+  BlkExprs.push_back(BlkCast);
+  // Add the user arguments.
+  for (CallExpr::arg_iterator I = Exp->arg_begin(), 
+       E = Exp->arg_end(); I != E; ++I) {
+    BlkExprs.push_back(*I);
+  }
+  CallExpr *CE = new (Context) CallExpr(*Context, PE, &BlkExprs[0],
+                                        BlkExprs.size(),
+                                        Exp->getType(), SourceLocation());
+  return CE;
+}
+
+void RewriteObjC::RewriteBlockCall(CallExpr *Exp) {
+  Stmt *BlockCall = SynthesizeBlockCall(Exp);
+  ReplaceStmt(Exp, BlockCall);
+}
+
+// We need to return the rewritten expression to handle cases where the
+// BlockDeclRefExpr is embedded in another expression being rewritten.
+// For example:
+//
+// int main() {
+//    __block Foo *f;
+//    __block int i;
+// 
+//    void (^myblock)() = ^() {
+//        [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten).
+//        i = 77;
+//    };
+//}
+Stmt *RewriteObjC::RewriteBlockDeclRefExpr(BlockDeclRefExpr *BDRE) {
+  // FIXME: Add more elaborate code generation required by the ABI.
+  Expr *DerefExpr = new (Context) UnaryOperator(BDRE, UnaryOperator::Deref,
+                             Context->getPointerType(BDRE->getType()),
+                             SourceLocation());
+  // Need parens to enforce precedence.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), DerefExpr);
+  ReplaceStmt(BDRE, PE);
+  return PE;
+}
+
+void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {
+  SourceLocation LocStart = CE->getLParenLoc();
+  SourceLocation LocEnd = CE->getRParenLoc();
+
+  // Need to avoid trying to rewrite synthesized casts.
+  if (LocStart.isInvalid())
+    return;
+  // Need to avoid trying to rewrite casts contained in macros.
+  if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
+    return;
+    
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  
+  // advance the location to startArgList.
+  const char *argPtr = startBuf;
+  
+  while (*argPtr++ && (argPtr < endBuf)) {
+    switch (*argPtr) {
+      case '^': 
+        // Replace the '^' with '*'.
+        LocStart = LocStart.getFileLocWithOffset(argPtr-startBuf);
+        ReplaceText(LocStart, 1, "*", 1);
+        break;
+    }
+  }
+  return;
+}
+
+void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
+  SourceLocation DeclLoc = FD->getLocation();
+  unsigned parenCount = 0;
+  
+  // We have 1 or more arguments that have closure pointers.
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *startArgList = strchr(startBuf, '(');
+  
+  assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
+  
+  parenCount++;
+  // advance the location to startArgList.
+  DeclLoc = DeclLoc.getFileLocWithOffset(startArgList-startBuf);
+  assert((DeclLoc.isValid()) && "Invalid DeclLoc");
+  
+  const char *argPtr = startArgList;
+  
+  while (*argPtr++ && parenCount) {
+    switch (*argPtr) {
+      case '^': 
+        // Replace the '^' with '*'.
+        DeclLoc = DeclLoc.getFileLocWithOffset(argPtr-startArgList);
+        ReplaceText(DeclLoc, 1, "*", 1);
+        break;
+      case '(': 
+        parenCount++; 
+        break;
+      case ')': 
+        parenCount--;
+        break;
+    }
+  }
+  return;
+}
+
+bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
+  const FunctionProtoType *FTP;
+  const PointerType *PT = QT->getAsPointerType();
+  if (PT) {
+    FTP = PT->getPointeeType()->getAsFunctionProtoType();
+  } else {
+    const BlockPointerType *BPT = QT->getAsBlockPointerType();
+    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+    FTP = BPT->getPointeeType()->getAsFunctionProtoType();
+  }
+  if (FTP) {
+    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 
+         E = FTP->arg_type_end(); I != E; ++I)
+      if (isTopLevelBlockPointerType(*I))
+        return true;
+  }
+  return false;
+}
+
+void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
+                                     const char *&RParen) {
+  const char *argPtr = strchr(Name, '(');
+  assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
+  
+  LParen = argPtr; // output the start.
+  argPtr++; // skip past the left paren.
+  unsigned parenCount = 1;
+  
+  while (*argPtr && parenCount) {
+    switch (*argPtr) {
+      case '(': parenCount++; break;
+      case ')': parenCount--; break;
+      default: break;
+    }
+    if (parenCount) argPtr++;
+  }
+  assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
+  RParen = argPtr; // output the end
+}
+
+void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+    RewriteBlockPointerFunctionArgs(FD);
+    return;
+  } 
+  // Handle Variables and Typedefs.
+  SourceLocation DeclLoc = ND->getLocation();
+  QualType DeclT;
+  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
+    DeclT = VD->getType();
+  else if (TypedefDecl *TDD = dyn_cast<TypedefDecl>(ND))
+    DeclT = TDD->getUnderlyingType();
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
+    DeclT = FD->getType();
+  else 
+    assert(0 && "RewriteBlockPointerDecl(): Decl type not yet handled");
+    
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *endBuf = startBuf;
+  // scan backward (from the decl location) for the end of the previous decl.
+  while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
+    startBuf--;
+    
+  // *startBuf != '^' if we are dealing with a pointer to function that
+  // may take block argument types (which will be handled below).
+  if (*startBuf == '^') {
+    // Replace the '^' with '*', computing a negative offset.
+    DeclLoc = DeclLoc.getFileLocWithOffset(startBuf-endBuf);
+    ReplaceText(DeclLoc, 1, "*", 1);
+  }
+  if (PointerTypeTakesAnyBlockArguments(DeclT)) {
+    // Replace the '^' with '*' for arguments.
+    DeclLoc = ND->getLocation();
+    startBuf = SM->getCharacterData(DeclLoc);
+    const char *argListBegin, *argListEnd;
+    GetExtentOfArgList(startBuf, argListBegin, argListEnd);
+    while (argListBegin < argListEnd) {
+      if (*argListBegin == '^') {
+        SourceLocation CaretLoc = DeclLoc.getFileLocWithOffset(argListBegin-startBuf);
+        ReplaceText(CaretLoc, 1, "*", 1);
+      }
+      argListBegin++;
+    }
+  }
+  return;
+}
+
+void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {  
+  // Add initializers for any closure decl refs.
+  GetBlockDeclRefExprs(Exp->getBody());
+  if (BlockDeclRefs.size()) {
+    // Unique all "by copy" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (!BlockDeclRefs[i]->isByRef())
+        BlockByCopyDecls.insert(BlockDeclRefs[i]->getDecl());
+    // Unique all "by ref" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->isByRef()) {
+        BlockByRefDecls.insert(BlockDeclRefs[i]->getDecl());
+      }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->getType()->isBlockPointerType()) {
+        GetBlockCallExprs(BlockDeclRefs[i]);
+        ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
+      }
+  }
+}
+
+FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(const char *name) {
+  IdentifierInfo *ID = &Context->Idents.get(name);
+  QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
+  return FunctionDecl::Create(*Context, TUDecl,SourceLocation(), 
+                              ID, FType, FunctionDecl::Extern, false,
+                              false);
+}
+
+Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
+  Blocks.push_back(Exp);
+
+  CollectBlockDeclRefInfo(Exp);
+  std::string FuncName;
+  
+  if (CurFunctionDef)
+    FuncName = CurFunctionDef->getNameAsString();
+  else if (CurMethodDef) {
+    FuncName = CurMethodDef->getSelector().getAsString();
+    // Convert colons to underscores.
+    std::string::size_type loc = 0;
+    while ((loc = FuncName.find(":", loc)) != std::string::npos)
+      FuncName.replace(loc, 1, "_");
+  } else if (GlobalVarDecl)
+    FuncName = std::string(GlobalVarDecl->getNameAsString());
+    
+  std::string BlockNumber = utostr(Blocks.size()-1);
+  
+  std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber;
+  std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
+  
+  // Get a pointer to the function type so we can cast appropriately.
+  QualType FType = Context->getPointerType(QualType(Exp->getFunctionType(),0));
+
+  FunctionDecl *FD;
+  Expr *NewRep;
+  
+  // Simulate a contructor call...
+  FD = SynthBlockInitFunctionDecl(Tag.c_str());
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, SourceLocation());
+  
+  llvm::SmallVector<Expr*, 4> InitExprs;
+  
+  // Initialize the block function.
+  FD = SynthBlockInitFunctionDecl(Func.c_str());
+  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(),
+                                               SourceLocation());
+  CastExpr *castExpr = new (Context) CStyleCastExpr(Context->VoidPtrTy, Arg, 
+                                          Context->VoidPtrTy, SourceLocation(),
+                                                    SourceLocation());
+  InitExprs.push_back(castExpr); 
+  
+  if (ImportedBlockDecls.size()) {
+    std::string Buf = "__" + FuncName + "_block_copy_" + BlockNumber;
+    FD = SynthBlockInitFunctionDecl(Buf.c_str());
+    Arg = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+    castExpr = new (Context) CStyleCastExpr(Context->VoidPtrTy, Arg, 
+                                  Context->VoidPtrTy, SourceLocation(),
+                                            SourceLocation());
+    InitExprs.push_back(castExpr); 
+    
+    Buf = "__" + FuncName + "_block_dispose_" + BlockNumber;
+    FD = SynthBlockInitFunctionDecl(Buf.c_str());
+    Arg = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+    castExpr = new (Context) CStyleCastExpr(Context->VoidPtrTy, Arg, 
+                                  Context->VoidPtrTy, SourceLocation(),
+                                            SourceLocation());
+    InitExprs.push_back(castExpr); 
+  }
+  // Add initializers for any closure decl refs.
+  if (BlockDeclRefs.size()) {
+    Expr *Exp;
+    // Output all "by copy" declarations.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      if (isObjCType((*I)->getType())) {
+        // FIXME: Conform to ABI ([[obj retain] autorelease]).
+        FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
+        Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+      } else if (isTopLevelBlockPointerType((*I)->getType())) {
+        FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
+        Arg = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+        Exp = new (Context) CStyleCastExpr(Context->VoidPtrTy, Arg, 
+                                 Context->VoidPtrTy, SourceLocation(),
+                                           SourceLocation());
+      } else {
+        FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
+        Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+      }
+      InitExprs.push_back(Exp); 
+    }
+    // Output all "by ref" declarations.
+    for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
+      Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+      Exp = new (Context) UnaryOperator(Exp, UnaryOperator::AddrOf,
+                              Context->getPointerType(Exp->getType()), 
+                              SourceLocation());
+      InitExprs.push_back(Exp); 
+    }
+  }
+  NewRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(),
+                                  FType, SourceLocation());
+  NewRep = new (Context) UnaryOperator(NewRep, UnaryOperator::AddrOf,
+                             Context->getPointerType(NewRep->getType()), 
+                             SourceLocation());
+  NewRep = new (Context) CStyleCastExpr(FType, NewRep, FType, SourceLocation(),
+                                        SourceLocation());
+  BlockDeclRefs.clear();
+  BlockByRefDecls.clear();
+  BlockByCopyDecls.clear();
+  ImportedBlockDecls.clear();
+  return NewRep;
+}
+
+//===----------------------------------------------------------------------===//
+// Function Body / Expression rewriting
+//===----------------------------------------------------------------------===//
+
+// This is run as a first "pass" prior to RewriteFunctionBodyOrGlobalInitializer().
+// The allows the main rewrite loop to associate all ObjCPropertyRefExprs with
+// their respective BinaryOperator. Without this knowledge, we'd need to rewrite
+// the ObjCPropertyRefExpr twice (once as a getter, and later as a setter).
+// Since the rewriter isn't capable of rewriting rewritten code, it's important
+// we get this right.
+void RewriteObjC::CollectPropertySetters(Stmt *S) {
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI)
+      CollectPropertySetters(*CI);
+
+  if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
+    if (BinOp->isAssignmentOp()) {
+      if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(BinOp->getLHS()))
+        PropSetters[PRE] = BinOp;
+    }
+  }
+}
+
+Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 
+      isa<DoStmt>(S) || isa<ForStmt>(S))
+    Stmts.push_back(S);
+  else if (isa<ObjCForCollectionStmt>(S)) {
+    Stmts.push_back(S);
+    ObjCBcLabelNo.push_back(++BcLabelCount);
+  }
+  
+  SourceRange OrigStmtRange = S->getSourceRange();
+  
+  // Perform a bottom up rewrite of all children.
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+       CI != E; ++CI)
+    if (*CI) {
+      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(*CI);
+      if (newStmt) 
+        *CI = newStmt;
+    }
+  
+  if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
+    // Rewrite the block body in place.
+    RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
+      
+    // Now we snarf the rewritten text and stash it away for later use.
+    std::string Str = Rewrite.getRewritenText(BE->getSourceRange());
+    RewrittenBlockExprs[BE] = Str;
+    
+    Stmt *blockTranscribed = SynthBlockInitExpr(BE);
+    //blockTranscribed->dump();
+    ReplaceStmt(S, blockTranscribed);
+    return blockTranscribed;
+  }
+  // Handle specific things.
+  if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
+    return RewriteAtEncode(AtEncode);
+  
+  if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S))
+    return RewriteObjCIvarRefExpr(IvarRefExpr, OrigStmtRange.getBegin());
+
+  if (ObjCPropertyRefExpr *PropRefExpr = dyn_cast<ObjCPropertyRefExpr>(S)) {
+    BinaryOperator *BinOp = PropSetters[PropRefExpr];
+    if (BinOp) {
+      // Because the rewriter doesn't allow us to rewrite rewritten code,
+      // we need to rewrite the right hand side prior to rewriting the setter.
+      DisableReplaceStmt = true;
+      // Save the source range. Even if we disable the replacement, the
+      // rewritten node will have been inserted into the tree. If the synthesized
+      // node is at the 'end', the rewriter will fail. Consider this:
+      //    self.errorHandler = handler ? handler : 
+      //              ^(NSURL *errorURL, NSError *error) { return (BOOL)1; };
+      SourceRange SrcRange = BinOp->getSourceRange();
+      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(BinOp->getRHS());
+      DisableReplaceStmt = false;
+      //
+      // Unlike the main iterator, we explicily avoid changing 'BinOp'. If
+      // we changed the RHS of BinOp, the rewriter would fail (since it needs
+      // to see the original expression). Consider this example:
+      //
+      // Foo *obj1, *obj2;
+      //
+      // obj1.i = [obj2 rrrr];
+      //
+      // 'BinOp' for the previous expression looks like:
+      //
+      // (BinaryOperator 0x231ccf0 'int' '='
+      //   (ObjCPropertyRefExpr 0x231cc70 'int' Kind=PropertyRef Property="i"
+      //     (DeclRefExpr 0x231cc50 'Foo *' Var='obj1' 0x231cbb0))
+      //   (ObjCMessageExpr 0x231ccb0 'int' selector=rrrr
+      //     (DeclRefExpr 0x231cc90 'Foo *' Var='obj2' 0x231cbe0)))
+      //
+      // 'newStmt' represents the rewritten message expression. For example:
+      //
+      // (CallExpr 0x231d300 'id':'struct objc_object *'
+      //   (ParenExpr 0x231d2e0 'int (*)(id, SEL)'
+      //     (CStyleCastExpr 0x231d2c0 'int (*)(id, SEL)'
+      //       (CStyleCastExpr 0x231d220 'void *'
+      //         (DeclRefExpr 0x231d200 'id (id, SEL, ...)' FunctionDecl='objc_msgSend' 0x231cdc0))))
+      //
+      // Note that 'newStmt' is passed to RewritePropertySetter so that it
+      // can be used as the setter argument. ReplaceStmt() will still 'see'
+      // the original RHS (since we haven't altered BinOp).
+      //
+      // This implies the Rewrite* routines can no longer delete the original 
+      // node. As a result, we now leak the original AST nodes.
+      //
+      return RewritePropertySetter(BinOp, dyn_cast<Expr>(newStmt), SrcRange);
+    } else {
+      return RewritePropertyGetter(PropRefExpr);
+    }
+  }
+  if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
+    return RewriteAtSelector(AtSelector);
+    
+  if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
+    return RewriteObjCStringLiteral(AtString);
+    
+  if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
+#if 0
+    // Before we rewrite it, put the original message expression in a comment.
+    SourceLocation startLoc = MessExpr->getLocStart();
+    SourceLocation endLoc = MessExpr->getLocEnd();
+    
+    const char *startBuf = SM->getCharacterData(startLoc);
+    const char *endBuf = SM->getCharacterData(endLoc);
+    
+    std::string messString;
+    messString += "// ";
+    messString.append(startBuf, endBuf-startBuf+1);
+    messString += "\n";
+        
+    // FIXME: Missing definition of 
+    // InsertText(clang::SourceLocation, char const*, unsigned int).
+    // InsertText(startLoc, messString.c_str(), messString.size());
+    // Tried this, but it didn't work either...
+    // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
+#endif
+    return RewriteMessageExpr(MessExpr);
+  }
+  
+  if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
+    return RewriteObjCTryStmt(StmtTry);
+
+  if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
+    return RewriteObjCSynchronizedStmt(StmtTry);
+
+  if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
+    return RewriteObjCThrowStmt(StmtThrow);
+  
+  if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
+    return RewriteObjCProtocolExpr(ProtocolExp);
+  
+  if (ObjCForCollectionStmt *StmtForCollection = 
+        dyn_cast<ObjCForCollectionStmt>(S))
+    return RewriteObjCForCollectionStmt(StmtForCollection, 
+                                        OrigStmtRange.getEnd());
+  if (BreakStmt *StmtBreakStmt =
+      dyn_cast<BreakStmt>(S))
+    return RewriteBreakStmt(StmtBreakStmt);
+  if (ContinueStmt *StmtContinueStmt =
+      dyn_cast<ContinueStmt>(S))
+    return RewriteContinueStmt(StmtContinueStmt);
+	
+  // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls 
+  // and cast exprs.
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
+    // FIXME: What we're doing here is modifying the type-specifier that
+    // precedes the first Decl.  In the future the DeclGroup should have
+    // a separate type-specifier that we can rewrite.    
+    RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin());
+    
+    // Blocks rewrite rules.
+    for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
+         DI != DE; ++DI) {
+      Decl *SD = *DI;
+      if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
+        if (isTopLevelBlockPointerType(ND->getType()))
+          RewriteBlockPointerDecl(ND);
+        else if (ND->getType()->isFunctionPointerType()) 
+          CheckFunctionPointerDecl(ND->getType(), ND);
+      }
+      if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
+        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+          RewriteBlockPointerDecl(TD);
+        else if (TD->getUnderlyingType()->isFunctionPointerType()) 
+          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+      }
+    }
+  }
+  
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S))
+    RewriteObjCQualifiedInterfaceTypes(CE);
+  
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 
+      isa<DoStmt>(S) || isa<ForStmt>(S)) {
+    assert(!Stmts.empty() && "Statement stack is empty");
+    assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) || 
+             isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back())) 
+            && "Statement stack mismatch");
+    Stmts.pop_back();
+  }
+  // Handle blocks rewriting.
+  if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
+    if (BDRE->isByRef())
+      return RewriteBlockDeclRefExpr(BDRE);
+  }
+  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
+    if (CE->getCallee()->getType()->isBlockPointerType()) {
+      Stmt *BlockCall = SynthesizeBlockCall(CE);
+      ReplaceStmt(S, BlockCall);
+      return BlockCall;
+    }
+  }
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) {
+    RewriteCastExpr(CE);
+  }
+#if 0
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
+    CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), ICE->getSubExpr(), SourceLocation());
+    // Get the new text.
+    std::string SStr;
+    llvm::raw_string_ostream Buf(SStr);
+    Replacement->printPretty(Buf);
+    const std::string &Str = Buf.str();
+
+    printf("CAST = %s\n", &Str[0]);
+    InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
+    delete S;
+    return Replacement;
+  }
+#endif
+  // Return this stmt unmodified.
+  return S;
+}
+
+/// HandleDeclInMainFile - This is called for each top-level decl defined in the
+/// main file of the input.
+void RewriteObjC::HandleDeclInMainFile(Decl *D) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (FD->isOverloadedOperator())
+      return;
+      
+    // Since function prototypes don't have ParmDecl's, we check the function
+    // prototype. This enables us to rewrite function declarations and
+    // definitions using the same code.
+    RewriteBlocksInFunctionProtoType(FD->getType(), FD);
+
+    // FIXME: If this should support Obj-C++, support CXXTryStmt
+    if (CompoundStmt *Body = FD->getCompoundBody(*Context)) {
+      CurFunctionDef = FD;
+      CollectPropertySetters(Body);
+      CurrentBody = Body;
+      Body =
+       cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+      FD->setBody(Body);
+      CurrentBody = 0;
+      if (PropParentMap) {
+        delete PropParentMap;
+        PropParentMap = 0;
+      }
+      // This synthesizes and inserts the block "impl" struct, invoke function,
+      // and any copy/dispose helper functions.
+      InsertBlockLiteralsWithinFunction(FD);
+      CurFunctionDef = 0;
+    } 
+    return;
+  }
+  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    if (CompoundStmt *Body = MD->getBody()) {
+      CurMethodDef = MD;
+      CollectPropertySetters(Body);
+      CurrentBody = Body;
+      Body =
+       cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+      MD->setBody(Body);
+      CurrentBody = 0;
+      if (PropParentMap) {
+        delete PropParentMap;
+        PropParentMap = 0;
+      }
+      InsertBlockLiteralsWithinMethod(MD);
+      CurMethodDef = 0;
+    }
+  }
+  if (ObjCImplementationDecl *CI = dyn_cast<ObjCImplementationDecl>(D))
+    ClassImplementation.push_back(CI);
+  else if (ObjCCategoryImplDecl *CI = dyn_cast<ObjCCategoryImplDecl>(D))
+    CategoryImplementation.push_back(CI);
+  else if (ObjCClassDecl *CD = dyn_cast<ObjCClassDecl>(D))
+    RewriteForwardClassDecl(CD);
+  else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    RewriteObjCQualifiedInterfaceTypes(VD);
+    if (isTopLevelBlockPointerType(VD->getType()))
+      RewriteBlockPointerDecl(VD);
+    else if (VD->getType()->isFunctionPointerType()) {
+      CheckFunctionPointerDecl(VD->getType(), VD);
+      if (VD->getInit()) {
+        if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+          RewriteCastExpr(CE);
+        }
+      }
+    }
+    if (VD->getInit()) {
+      GlobalVarDecl = VD;
+      CollectPropertySetters(VD->getInit());
+      CurrentBody = VD->getInit();
+      RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
+      CurrentBody = 0;
+      if (PropParentMap) {
+        delete PropParentMap;
+        PropParentMap = 0;
+      }
+      SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), 
+                              VD->getNameAsCString());
+      GlobalVarDecl = 0;
+
+      // This is needed for blocks.
+      if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+        RewriteCastExpr(CE);
+      }
+    }
+    return;
+  }
+  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+    if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+      RewriteBlockPointerDecl(TD);
+    else if (TD->getUnderlyingType()->isFunctionPointerType()) 
+      CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+    return;
+  }
+  if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
+    if (RD->isDefinition()) {
+      for (RecordDecl::field_iterator i = RD->field_begin(*Context), 
+             e = RD->field_end(*Context); i != e; ++i) {
+        FieldDecl *FD = *i;
+        if (isTopLevelBlockPointerType(FD->getType()))
+          RewriteBlockPointerDecl(FD);
+      }
+    }
+    return;
+  }
+  // Nothing yet.
+}
+
+void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
+  // Get the top-level buffer that this corresponds to.
+  
+  // Rewrite tabs if we care.
+  //RewriteTabs();
+  
+  if (Diags.hasErrorOccurred())
+    return;
+  
+  RewriteInclude();
+  
+  // Here's a great place to add any extra declarations that may be needed.
+  // Write out meta data for each @protocol(<expr>).
+  for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(), 
+       E = ProtocolExprDecls.end(); I != E; ++I)
+    RewriteObjCProtocolMetaData(*I, "", "", Preamble);
+
+  InsertText(SM->getLocForStartOfFile(MainFileID), 
+             Preamble.c_str(), Preamble.size(), false);
+  if (ClassImplementation.size() || CategoryImplementation.size())
+    RewriteImplementations();
+
+  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
+  // we are done.
+  if (const RewriteBuffer *RewriteBuf = 
+      Rewrite.getRewriteBufferFor(MainFileID)) {
+    //printf("Changed:\n");
+    *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
+  } else {
+    fprintf(stderr, "No changes\n");
+  }
+
+  if (ClassImplementation.size() || CategoryImplementation.size() ||
+      ProtocolExprDecls.size()) {
+    // Rewrite Objective-c meta data*
+    std::string ResultStr;
+    SynthesizeMetaDataIntoBuffer(ResultStr);
+    // Emit metadata.
+    *OutFile << ResultStr;
+  }
+  OutFile->flush();
+}
+
