//===--- 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/Rewrite/Frontend/ASTConsumers.h"
#include "clang/Rewrite/Core/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/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/DenseSet.h"

using namespace clang;
using llvm::utostr;

namespace {
  class RewriteModernObjC : public ASTConsumer {
  protected:
    
    enum {
      BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)),
                                        block, ... */
      BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
      BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the 
                                        __block variable */
      BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy
                                        helpers */
      BLOCK_BYREF_CALLER      = 128, /* called from __block (byref) copy/dispose
                                        support routines */
      BLOCK_BYREF_CURRENT_MAX = 256
    };
    
    enum {
      BLOCK_NEEDS_FREE =        (1 << 24),
      BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
      BLOCK_HAS_CXX_OBJ =       (1 << 26),
      BLOCK_IS_GC =             (1 << 27),
      BLOCK_IS_GLOBAL =         (1 << 28),
      BLOCK_HAS_DESCRIPTOR =    (1 << 29)
    };
    static const int OBJC_ABI_VERSION = 7;
    
    Rewriter Rewrite;
    DiagnosticsEngine &Diags;
    const LangOptions &LangOpts;
    ASTContext *Context;
    SourceManager *SM;
    TranslationUnitDecl *TUDecl;
    FileID MainFileID;
    const char *MainFileStart, *MainFileEnd;
    Stmt *CurrentBody;
    ParentMap *PropParentMap; // created lazily.
    std::string InFileName;
    raw_ostream* OutFile;
    std::string Preamble;
    
    TypeDecl *ProtocolTypeDecl;
    VarDecl *GlobalVarDecl;
    Expr *GlobalConstructionExp;
    unsigned RewriteFailedDiag;
    unsigned GlobalBlockRewriteFailedDiag;
    // ObjC string constant support.
    unsigned NumObjCStringLiterals;
    VarDecl *ConstantStringClassReference;
    RecordDecl *NSStringRecord;

    // ObjC foreach break/continue generation support.
    int BcLabelCount;
    
    unsigned TryFinallyContainsReturnDiag;
    // Needed for super.
    ObjCMethodDecl *CurMethodDef;
    RecordDecl *SuperStructDecl;
    RecordDecl *ConstantStringDecl;
    
    FunctionDecl *MsgSendFunctionDecl;
    FunctionDecl *MsgSendSuperFunctionDecl;
    FunctionDecl *MsgSendStretFunctionDecl;
    FunctionDecl *MsgSendSuperStretFunctionDecl;
    FunctionDecl *MsgSendFpretFunctionDecl;
    FunctionDecl *GetClassFunctionDecl;
    FunctionDecl *GetMetaClassFunctionDecl;
    FunctionDecl *GetSuperClassFunctionDecl;
    FunctionDecl *SelGetUidFunctionDecl;
    FunctionDecl *CFStringFunctionDecl;
    FunctionDecl *SuperContructorFunctionDecl;
    FunctionDecl *CurFunctionDef;

    /* Misc. containers needed for meta-data rewrite. */
    SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
    SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
    llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
    llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags;
    SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
    /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
    SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses;
    
    /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
    llvm::SmallVector<ObjCCategoryDecl*, 8> DefinedNonLazyCategories;
    
    SmallVector<Stmt *, 32> Stmts;
    SmallVector<int, 8> ObjCBcLabelNo;
    // Remember all the @protocol(<expr>) expressions.
    llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
    
    llvm::DenseSet<uint64_t> CopyDestroyCache;

    // Block expressions.
    SmallVector<BlockExpr *, 32> Blocks;
    SmallVector<int, 32> InnerDeclRefsCount;
    SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
    
    SmallVector<DeclRefExpr *, 32> BlockDeclRefs;

    // Block related declarations.
    SmallVector<ValueDecl *, 8> BlockByCopyDecls;
    llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
    SmallVector<ValueDecl *, 8> BlockByRefDecls;
    llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
    llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
    llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
    llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
    
    llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
    llvm::DenseMap<ObjCInterfaceDecl *, 
                    llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars;
    
    // 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;

    // Needed for header files being rewritten
    bool IsHeader;
    bool SilenceRewriteMacroWarning;
    bool objc_impl_method;
    
    bool DisableReplaceStmt;
    class DisableReplaceStmtScope {
      RewriteModernObjC &R;
      bool SavedValue;
    
    public:
      DisableReplaceStmtScope(RewriteModernObjC &R)
        : R(R), SavedValue(R.DisableReplaceStmt) {
        R.DisableReplaceStmt = true;
      }
      ~DisableReplaceStmtScope() {
        R.DisableReplaceStmt = SavedValue;
      }
    };
    void InitializeCommon(ASTContext &context);

  public:
    llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
    // Top Level Driver code.
    virtual bool HandleTopLevelDecl(DeclGroupRef D) {
      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
        if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
          if (!Class->isThisDeclarationADefinition()) {
            RewriteForwardClassDecl(D);
            break;
          } else {
            // Keep track of all interface declarations seen.
            ObjCInterfacesSeen.push_back(Class);
            break;
          }
        }

        if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) {
          if (!Proto->isThisDeclarationADefinition()) {
            RewriteForwardProtocolDecl(D);
            break;
          }
        }

        HandleTopLevelSingleDecl(*I);
      }
      return true;
    }
    void HandleTopLevelSingleDecl(Decl *D);
    void HandleDeclInMainFile(Decl *D);
    RewriteModernObjC(std::string inFile, raw_ostream *OS,
                DiagnosticsEngine &D, const LangOptions &LOpts,
                bool silenceMacroWarn);
    
    ~RewriteModernObjC() {}
    
    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;

      // 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) {
      if (DisableReplaceStmt)
        return;

      // Measure 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, 0, PrintingPolicy(LangOpts));
      const std::string &Str = S.str();

      // If replacement succeeded or warning disabled return with no warning.
      if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
        ReplacedNodes[Old] = New;
        return;
      }
      if (SilenceRewriteMacroWarning)
        return;
      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
                   << Old->getSourceRange();
    }

    void InsertText(SourceLocation Loc, StringRef Str,
                    bool InsertAfter = true) {
      // If insertion succeeded or warning disabled return with no warning.
      if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
          SilenceRewriteMacroWarning)
        return;

      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
    }

    void ReplaceText(SourceLocation Start, unsigned OrigLength,
                     StringRef Str) {
      // If removal succeeded or warning disabled return with no warning.
      if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
          SilenceRewriteMacroWarning)
        return;

      Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
    }

    // Syntactic Rewriting.
    void RewriteRecordBody(RecordDecl *RD);
    void RewriteInclude();
    void RewriteLineDirective(const Decl *D);
    void ConvertSourceLocationToLineDirective(SourceLocation Loc,
                                              std::string &LineString);
    void RewriteForwardClassDecl(DeclGroupRef D);
    void RewriteForwardClassDecl(const llvm::SmallVector<Decl*, 8> &DG);
    void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 
                                     const std::string &typedefString);
    void RewriteImplementations();
    void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
                                 ObjCImplementationDecl *IMD,
                                 ObjCCategoryImplDecl *CID);
    void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
    void RewriteImplementationDecl(Decl *Dcl);
    void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
                               ObjCMethodDecl *MDecl, std::string &ResultStr);
    void RewriteTypeIntoString(QualType T, std::string &ResultStr,
                               const FunctionType *&FPRetType);
    void RewriteByRefString(std::string &ResultStr, const std::string &Name,
                            ValueDecl *VD, bool def=false);
    void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
    void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
    void RewriteForwardProtocolDecl(DeclGroupRef D);
    void RewriteForwardProtocolDecl(const llvm::SmallVector<Decl*, 8> &DG);
    void RewriteMethodDeclaration(ObjCMethodDecl *Method);
    void RewriteProperty(ObjCPropertyDecl *prop);
    void RewriteFunctionDecl(FunctionDecl *FD);
    void RewriteBlockPointerType(std::string& Str, QualType Type);
    void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
    void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
    void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
    void RewriteTypeOfDecl(VarDecl *VD);
    void RewriteObjCQualifiedInterfaceTypes(Expr *E);
    
    std::string getIvarAccessString(ObjCIvarDecl *D);
  
    // Expression Rewriting.
    Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
    Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
    Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo);
    Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo);
    Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
    Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
    Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
    Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp);
    Stmt *RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp);
    Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp);
    Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp);
    Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
    Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
    Stmt *RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt  *S);
    Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
    Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
    Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
                                       SourceLocation OrigEnd);
    Stmt *RewriteBreakStmt(BreakStmt *S);
    Stmt *RewriteContinueStmt(ContinueStmt *S);
    void RewriteCastExpr(CStyleCastExpr *CE);
    void RewriteImplicitCastObjCExpr(CastExpr *IE);
    void RewriteLinkageSpec(LinkageSpecDecl *LSD);
    
    // Block rewriting.
    void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
    
    // Block specific rewrite rules.
    void RewriteBlockPointerDecl(NamedDecl *VD);
    void RewriteByRefVar(VarDecl *VD, bool firstDecl, bool lastDecl);
    Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
    Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
    void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
    
    void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
                                      std::string &Result);
    
    void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result);
    bool IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, TagDecl *Tag,
                                 bool &IsNamedDefinition);
    void RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 
                                              std::string &Result);
    
    bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result);
    
    void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
                                  std::string &Result);
    
    virtual void Initialize(ASTContext &context);
    
    // Misc. AST transformation routines. Sometimes they end up calling
    // rewriting routines on the new ASTs.
    CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
                                           Expr **args, unsigned nargs,
                                           SourceLocation StartLoc=SourceLocation(),
                                           SourceLocation EndLoc=SourceLocation());
    
    Expr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
                                        QualType msgSendType, 
                                        QualType returnType, 
                                        SmallVectorImpl<QualType> &ArgTypes,
                                        SmallVectorImpl<Expr*> &MsgExprs,
                                        ObjCMethodDecl *Method);

    Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
                           SourceLocation StartLoc=SourceLocation(),
                           SourceLocation EndLoc=SourceLocation());
    
    void SynthCountByEnumWithState(std::string &buf);
    void SynthMsgSendFunctionDecl();
    void SynthMsgSendSuperFunctionDecl();
    void SynthMsgSendStretFunctionDecl();
    void SynthMsgSendFpretFunctionDecl();
    void SynthMsgSendSuperStretFunctionDecl();
    void SynthGetClassFunctionDecl();
    void SynthGetMetaClassFunctionDecl();
    void SynthGetSuperClassFunctionDecl();
    void SynthSelGetUidFunctionDecl();
    void SynthSuperContructorFunctionDecl();
    
    // Rewriting metadata
    template<typename MethodIterator>
    void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
                                    MethodIterator MethodEnd,
                                    bool IsInstanceMethod,
                                    StringRef prefix,
                                    StringRef ClassName,
                                    std::string &Result);
    void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
                                     std::string &Result);
    void RewriteObjCProtocolListMetaData(
                   const ObjCList<ObjCProtocolDecl> &Prots,
                   StringRef prefix, StringRef ClassName, std::string &Result);
    void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
                                          std::string &Result);
    void RewriteClassSetupInitHook(std::string &Result);
    
    void RewriteMetaDataIntoBuffer(std::string &Result);
    void WriteImageInfo(std::string &Result);
    void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
                                             std::string &Result);
    void RewriteCategorySetupInitHook(std::string &Result);
    
    // Rewriting ivar
    void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
                                              std::string &Result);
    Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV);

    
    std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag);
    std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
                                      StringRef funcName, std::string Tag);
    std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
                                      StringRef funcName, std::string Tag);
    std::string SynthesizeBlockImpl(BlockExpr *CE, 
                                    std::string Tag, std::string Desc);
    std::string SynthesizeBlockDescriptor(std::string DescTag, 
                                          std::string ImplTag,
                                          int i, StringRef funcName,
                                          unsigned hasCopy);
    Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
    void SynthesizeBlockLiterals(SourceLocation FunLocStart,
                                 StringRef FunName);
    FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
    Stmt *SynthBlockInitExpr(BlockExpr *Exp,
            const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs);

    // Misc. helper routines.
    QualType getProtocolType();
    void WarnAboutReturnGotoStmts(Stmt *S);
    void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
    void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
    void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);

    bool IsDeclStmtInForeachHeader(DeclStmt *DS);
    void CollectBlockDeclRefInfo(BlockExpr *Exp);
    void GetBlockDeclRefExprs(Stmt *S);
    void GetInnerBlockDeclRefExprs(Stmt *S, 
                SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs,
                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);

    // 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);
    }

    /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
    /// to a function pointer type and upon success, returns true; false
    /// otherwise.
    bool convertBlockPointerToFunctionPointer(QualType &T) {
      if (isTopLevelBlockPointerType(T)) {
        const BlockPointerType *BPT = T->getAs<BlockPointerType>();
        T = Context->getPointerType(BPT->getPointeeType());
        return true;
      }
      return false;
    }
    
    bool convertObjCTypeToCStyleType(QualType &T);
    
    bool needToScanForQualifiers(QualType T);
    QualType getSuperStructType();
    QualType getConstantStringStructType();
    QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
    bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
    
    void convertToUnqualifiedObjCType(QualType &T) {
      if (T->isObjCQualifiedIdType()) {
        bool isConst = T.isConstQualified();
        T = isConst ? Context->getObjCIdType().withConst() 
                    : Context->getObjCIdType();
      }
      else if (T->isObjCQualifiedClassType())
        T = Context->getObjCClassType();
      else if (T->isObjCObjectPointerType() &&
               T->getPointeeType()->isObjCQualifiedInterfaceType()) {
        if (const ObjCObjectPointerType * OBJPT =
              T->getAsObjCInterfacePointerType()) {
          const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
          T = QualType(IFaceT, 0);
          T = Context->getPointerType(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->getAs<PointerType>()) {
        if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
            PT->getPointeeType()->isObjCQualifiedIdType())
          return true;
      }
      return false;
    }
    bool PointerTypeTakesAnyBlockArguments(QualType QT);
    bool PointerTypeTakesAnyObjCQualifiedType(QualType QT);
    void GetExtentOfArgList(const char *Name, const char *&LParen,
                            const char *&RParen);
    
    void QuoteDoublequotes(std::string &From, std::string &To) {
      for (unsigned i = 0; i < From.length(); i++) {
        if (From[i] == '"')
          To += "\\\"";
        else
          To += From[i];
      }
    }

    QualType getSimpleFunctionType(QualType result,
                                   const QualType *args,
                                   unsigned numArgs,
                                   bool variadic = false) {
      if (result == Context->getObjCInstanceType())
        result =  Context->getObjCIdType();
      FunctionProtoType::ExtProtoInfo fpi;
      fpi.Variadic = variadic;
      return Context->getFunctionType(result, args, numArgs, fpi);
    }

    // Helper function: create a CStyleCastExpr with trivial type source info.
    CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
                                             CastKind Kind, Expr *E) {
      TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
      return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, 0, TInfo,
                                    SourceLocation(), SourceLocation());
    }
    
    bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
      IdentifierInfo* II = &Context->Idents.get("load");
      Selector LoadSel = Context->Selectors.getSelector(0, &II);
      return OD->getClassMethod(LoadSel) != 0;
    }
  };
  
}

void RewriteModernObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
                                                   NamedDecl *D) {
  if (const FunctionProtoType *fproto
      = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) {
    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 RewriteModernObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
  const PointerType *PT = funcType->getAs<PointerType>();
  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";
}

RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS,
                         DiagnosticsEngine &D, const LangOptions &LOpts,
                         bool silenceMacroWarn)
      : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
        SilenceRewriteMacroWarning(silenceMacroWarn) {
  IsHeader = IsHeaderFile(inFile);
  RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
               "rewriting sub-expression within a macro (may not be correct)");
  // FIXME. This should be an error. But if block is not called, it is OK. And it
  // may break including some headers.
  GlobalBlockRewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
    "rewriting block literal declared in global scope is not implemented");
          
  TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
               DiagnosticsEngine::Warning,
               "rewriter doesn't support user-specified control flow semantics "
               "for @try/@finally (code may not execute properly)");
}

ASTConsumer *clang::CreateModernObjCRewriter(const std::string& InFile,
                                       raw_ostream* OS,
                                       DiagnosticsEngine &Diags,
                                       const LangOptions &LOpts,
                                       bool SilenceRewriteMacroWarning) {
    return new RewriteModernObjC(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning);
}

void RewriteModernObjC::InitializeCommon(ASTContext &context) {
  Context = &context;
  SM = &Context->getSourceManager();
  TUDecl = Context->getTranslationUnitDecl();
  MsgSendFunctionDecl = 0;
  MsgSendSuperFunctionDecl = 0;
  MsgSendStretFunctionDecl = 0;
  MsgSendSuperStretFunctionDecl = 0;
  MsgSendFpretFunctionDecl = 0;
  GetClassFunctionDecl = 0;
  GetMetaClassFunctionDecl = 0;
  GetSuperClassFunctionDecl = 0;
  SelGetUidFunctionDecl = 0;
  CFStringFunctionDecl = 0;
  ConstantStringClassReference = 0;
  NSStringRecord = 0;
  CurMethodDef = 0;
  CurFunctionDef = 0;
  GlobalVarDecl = 0;
  GlobalConstructionExp = 0;
  SuperStructDecl = 0;
  ProtocolTypeDecl = 0;
  ConstantStringDecl = 0;
  BcLabelCount = 0;
  SuperContructorFunctionDecl = 0;
  NumObjCStringLiterals = 0;
  PropParentMap = 0;
  CurrentBody = 0;
  DisableReplaceStmt = false;
  objc_impl_method = 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->getLangOpts());
}

//===----------------------------------------------------------------------===//
// Top Level Driver Code
//===----------------------------------------------------------------------===//

void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) {
  if (Diags.hasErrorOccurred())
    return;

  // 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->getExpansionLoc(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 (FVD->getName() == "_NSConstantStringClassReference") {
      ConstantStringClassReference = FVD;
      return;
    }
  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
    RewriteCategoryDecl(CD);
  } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
    if (PD->isThisDeclarationADefinition())
      RewriteProtocolDecl(PD);
  } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
    // FIXME. This will not work in all situations and leaving it out
    // is harmless.
    // RewriteLinkageSpec(LSD);
    
    // Recurse into linkage specifications
    for (DeclContext::decl_iterator DI = LSD->decls_begin(),
                                 DIEnd = LSD->decls_end();
         DI != DIEnd; ) {
      if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
        if (!IFace->isThisDeclarationADefinition()) {
          SmallVector<Decl *, 8> DG;
          SourceLocation StartLoc = IFace->getLocStart();
          do {
            if (isa<ObjCInterfaceDecl>(*DI) &&
                !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
                StartLoc == (*DI)->getLocStart())
              DG.push_back(*DI);
            else
              break;
            
            ++DI;
          } while (DI != DIEnd);
          RewriteForwardClassDecl(DG);
          continue;
        }
        else {
          // Keep track of all interface declarations seen.
          ObjCInterfacesSeen.push_back(IFace);
          ++DI;
          continue;
        }
      }

      if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) {
        if (!Proto->isThisDeclarationADefinition()) {
          SmallVector<Decl *, 8> DG;
          SourceLocation StartLoc = Proto->getLocStart();
          do {
            if (isa<ObjCProtocolDecl>(*DI) &&
                !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
                StartLoc == (*DI)->getLocStart())
              DG.push_back(*DI);
            else
              break;
            
            ++DI;
          } while (DI != DIEnd);
          RewriteForwardProtocolDecl(DG);
          continue;
        }
      }
      
      HandleTopLevelSingleDecl(*DI);
      ++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 RewriteModernObjC::RewriteInclude() {
  SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
  StringRef MainBuf = SM->getBufferData(MainFileID);
  const char *MainBufStart = MainBuf.begin();
  const char *MainBufEnd = MainBuf.end();
  size_t ImportLen = strlen("import");

  // 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.getLocWithOffset(BufPtr-MainBufStart);
        ReplaceText(ImportLoc, ImportLen, "include");
        BufPtr += ImportLen;
      }
    }
  }
}

static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl,
                                  ObjCIvarDecl *IvarDecl, std::string &Result) {
  Result += "OBJC_IVAR_$_";
  Result += IDecl->getName();
  Result += "$";
  Result += IvarDecl->getName();
}

std::string 
RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) {
  const ObjCInterfaceDecl *ClassDecl = D->getContainingInterface();
  
  // Build name of symbol holding ivar offset.
  std::string IvarOffsetName;
  WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
  
  
  std::string S = "(*(";
  QualType IvarT = D->getType();
  
  if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
    RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
    RD = RD->getDefinition();
    if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
      // decltype(((Foo_IMPL*)0)->bar) *
      ObjCContainerDecl *CDecl = 
      dyn_cast<ObjCContainerDecl>(D->getDeclContext());
      // ivar in class extensions requires special treatment.
      if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
        CDecl = CatDecl->getClassInterface();
      std::string RecName = CDecl->getName();
      RecName += "_IMPL";
      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                          SourceLocation(), SourceLocation(),
                                          &Context->Idents.get(RecName.c_str()));
      QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
      unsigned UnsignedIntSize = 
      static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
      Expr *Zero = IntegerLiteral::Create(*Context,
                                          llvm::APInt(UnsignedIntSize, 0),
                                          Context->UnsignedIntTy, SourceLocation());
      Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
      ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
                                              Zero);
      FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
                                        SourceLocation(),
                                        &Context->Idents.get(D->getNameAsString()),
                                        IvarT, 0,
                                        /*BitWidth=*/0, /*Mutable=*/true,
                                        ICIS_NoInit);
      MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
                                                FD->getType(), VK_LValue,
                                                OK_Ordinary);
      IvarT = Context->getDecltypeType(ME, ME->getType());
    }
  }
  convertObjCTypeToCStyleType(IvarT);
  QualType castT = Context->getPointerType(IvarT);
  std::string TypeString(castT.getAsString(Context->getPrintingPolicy()));
  S += TypeString;
  S += ")";
  
  // ((char *)self + IVAR_OFFSET_SYMBOL_NAME)
  S += "((char *)self + ";
  S += IvarOffsetName;
  S += "))";
  ReferencedIvars[const_cast<ObjCInterfaceDecl *>(ClassDecl)].insert(D);
  return S;
}

/// mustSynthesizeSetterGetterMethod - returns true if setter or getter has not
/// been found in the class implementation. In this case, it must be synthesized.
static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP,
                                             ObjCPropertyDecl *PD,
                                             bool getter) {
  return getter ? !IMP->getInstanceMethod(PD->getGetterName())
                : !IMP->getInstanceMethod(PD->getSetterName());
  
}

void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
                                          ObjCImplementationDecl *IMD,
                                          ObjCCategoryImplDecl *CID) {
  static bool objcGetPropertyDefined = false;
  static bool objcSetPropertyDefined = false;
  SourceLocation startGetterSetterLoc;
  
  if (PID->getLocStart().isValid()) {
    SourceLocation startLoc = PID->getLocStart();
    InsertText(startLoc, "// ");
    const char *startBuf = SM->getCharacterData(startLoc);
    assert((*startBuf == '@') && "bogus @synthesize location");
    const char *semiBuf = strchr(startBuf, ';');
    assert((*semiBuf == ';') && "@synthesize: can't find ';'");
    startGetterSetterLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
  }
  else
    startGetterSetterLoc = IMD ? IMD->getLocEnd() : CID->getLocEnd();

  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
    return; // FIXME: is this correct?

  // Generate the 'getter' function.
  ObjCPropertyDecl *PD = PID->getPropertyDecl();
  ObjCIvarDecl *OID = PID->getPropertyIvarDecl();

  if (!OID)
    return;
  unsigned Attributes = PD->getPropertyAttributes();
  if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) {
    bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
                          (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
                                         ObjCPropertyDecl::OBJC_PR_copy));
    std::string Getr;
    if (GenGetProperty && !objcGetPropertyDefined) {
      objcGetPropertyDefined = true;
      // FIXME. Is this attribute correct in all cases?
      Getr = "\nextern \"C\" __declspec(dllimport) "
            "id objc_getProperty(id, SEL, long, bool);\n";
    }
    RewriteObjCMethodDecl(OID->getContainingInterface(),  
                          PD->getGetterMethodDecl(), Getr);
    Getr += "{ ";
    // Synthesize an explicit cast to gain access to the ivar.
    // See objc-act.c:objc_synthesize_new_getter() for details.
    if (GenGetProperty) {
      // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
      Getr += "typedef ";
      const FunctionType *FPRetType = 0;
      RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr, 
                            FPRetType);
      Getr += " _TYPE";
      if (FPRetType) {
        Getr += ")"; // close the precedence "scope" for "*".
      
        // Now, emit the argument types (if any).
        if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){
          Getr += "(";
          for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
            if (i) Getr += ", ";
            std::string ParamStr = FT->getArgType(i).getAsString(
                                                          Context->getPrintingPolicy());
            Getr += ParamStr;
          }
          if (FT->isVariadic()) {
            if (FT->getNumArgs()) Getr += ", ";
            Getr += "...";
          }
          Getr += ")";
        } else
          Getr += "()";
      }
      Getr += ";\n";
      Getr += "return (_TYPE)";
      Getr += "objc_getProperty(self, _cmd, ";
      RewriteIvarOffsetComputation(OID, Getr);
      Getr += ", 1)";
    }
    else
      Getr += "return " + getIvarAccessString(OID);
    Getr += "; }";
    InsertText(startGetterSetterLoc, Getr);
  }
  
  if (PD->isReadOnly() || 
      !mustSynthesizeSetterGetterMethod(IMD, PD, false /*setter*/))
    return;

  // Generate the 'setter' function.
  std::string Setr;
  bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
                                      ObjCPropertyDecl::OBJC_PR_copy);
  if (GenSetProperty && !objcSetPropertyDefined) {
    objcSetPropertyDefined = true;
    // FIXME. Is this attribute correct in all cases?
    Setr = "\nextern \"C\" __declspec(dllimport) "
    "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
  }
  
  RewriteObjCMethodDecl(OID->getContainingInterface(), 
                        PD->getSetterMethodDecl(), Setr);
  Setr += "{ ";
  // Synthesize an explicit cast to initialize the ivar.
  // See objc-act.c:objc_synthesize_new_setter() for details.
  if (GenSetProperty) {
    Setr += "objc_setProperty (self, _cmd, ";
    RewriteIvarOffsetComputation(OID, Setr);
    Setr += ", (id)";
    Setr += PD->getName();
    Setr += ", ";
    if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
      Setr += "0, ";
    else
      Setr += "1, ";
    if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
      Setr += "1)";
    else
      Setr += "0)";
  }
  else {
    Setr += getIvarAccessString(OID) + " = ";
    Setr += PD->getName();
  }
  Setr += "; }\n";
  InsertText(startGetterSetterLoc, Setr);
}

static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
                                       std::string &typedefString) {
  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();
  // typedef struct { } _objc_exc_Classname;
  typedefString += ";\ntypedef struct {} _objc_exc_";
  typedefString += ForwardDecl->getNameAsString();
  typedefString += ";\n#endif\n";
}

void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
                                              const std::string &typedefString) {
    SourceLocation startLoc = ClassDecl->getLocStart();
    const char *startBuf = SM->getCharacterData(startLoc);
    const char *semiPtr = strchr(startBuf, ';'); 
    // Replace the @class with typedefs corresponding to the classes.
    ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);  
}

void RewriteModernObjC::RewriteForwardClassDecl(DeclGroupRef D) {
  std::string typedefString;
  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
    ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(*I);
    if (I == D.begin()) {
      // 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.
      typedefString += "// @class ";
      typedefString += ForwardDecl->getNameAsString();
      typedefString += ";\n";
    }
    RewriteOneForwardClassDecl(ForwardDecl, typedefString);
  }
  DeclGroupRef::iterator I = D.begin();
  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
}

void RewriteModernObjC::RewriteForwardClassDecl(
                                const llvm::SmallVector<Decl*, 8> &D) {
  std::string typedefString;
  for (unsigned i = 0; i < D.size(); i++) {
    ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]);
    if (i == 0) {
      typedefString += "// @class ";
      typedefString += ForwardDecl->getNameAsString();
      typedefString += ";\n";
    }
    RewriteOneForwardClassDecl(ForwardDecl, typedefString);
  }
  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
}

void RewriteModernObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
  // When method is a synthesized one, such as a getter/setter there is
  // nothing to rewrite.
  if (Method->isImplicit())
    return;
  SourceLocation LocStart = Method->getLocStart();
  SourceLocation LocEnd = Method->getLocEnd();

  if (SM->getExpansionLineNumber(LocEnd) >
      SM->getExpansionLineNumber(LocStart)) {
    InsertText(LocStart, "#if 0\n");
    ReplaceText(LocEnd, 1, ";\n#endif\n");
  } else {
    InsertText(LocStart, "// ");
  }
}

void RewriteModernObjC::RewriteProperty(ObjCPropertyDecl *prop) {
  SourceLocation Loc = prop->getAtLoc();

  ReplaceText(Loc, 0, "// ");
  // FIXME: handle properties that are declared across multiple lines.
}

void RewriteModernObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
  SourceLocation LocStart = CatDecl->getLocStart();

  // FIXME: handle category headers that are declared across multiple lines.
  if (CatDecl->getIvarRBraceLoc().isValid()) {
    ReplaceText(LocStart, 1, "/** ");
    ReplaceText(CatDecl->getIvarRBraceLoc(), 1, "**/ ");
  }
  else {
    ReplaceText(LocStart, 0, "// ");
  }
  
  for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(),
       E = CatDecl->prop_end(); I != E; ++I)
    RewriteProperty(*I);
  
  for (ObjCCategoryDecl::instmeth_iterator
         I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
       I != E; ++I)
    RewriteMethodDeclaration(*I);
  for (ObjCCategoryDecl::classmeth_iterator
         I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
       I != E; ++I)
    RewriteMethodDeclaration(*I);

  // Lastly, comment out the @end.
  ReplaceText(CatDecl->getAtEndRange().getBegin(), 
              strlen("@end"), "/* @end */");
}

void RewriteModernObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
  SourceLocation LocStart = PDecl->getLocStart();
  assert(PDecl->isThisDeclarationADefinition());
  
  // FIXME: handle protocol headers that are declared across multiple lines.
  ReplaceText(LocStart, 0, "// ");

  for (ObjCProtocolDecl::instmeth_iterator
         I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
       I != E; ++I)
    RewriteMethodDeclaration(*I);
  for (ObjCProtocolDecl::classmeth_iterator
         I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
       I != E; ++I)
    RewriteMethodDeclaration(*I);

  for (ObjCInterfaceDecl::prop_iterator I = PDecl->prop_begin(),
       E = PDecl->prop_end(); I != E; ++I)
    RewriteProperty(*I);
  
  // Lastly, comment out the @end.
  SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
  ReplaceText(LocEnd, strlen("@end"), "/* @end */");

  // 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"))) {
      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
      ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");

    }
    else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
      ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");

    }
  }
}

void RewriteModernObjC::RewriteForwardProtocolDecl(DeclGroupRef D) {
  SourceLocation LocStart = (*D.begin())->getLocStart();
  if (LocStart.isInvalid())
    llvm_unreachable("Invalid SourceLocation");
  // FIXME: handle forward protocol that are declared across multiple lines.
  ReplaceText(LocStart, 0, "// ");
}

void 
RewriteModernObjC::RewriteForwardProtocolDecl(const llvm::SmallVector<Decl*, 8> &DG) {
  SourceLocation LocStart = DG[0]->getLocStart();
  if (LocStart.isInvalid())
    llvm_unreachable("Invalid SourceLocation");
  // FIXME: handle forward protocol that are declared across multiple lines.
  ReplaceText(LocStart, 0, "// ");
}

void 
RewriteModernObjC::RewriteLinkageSpec(LinkageSpecDecl *LSD) {
  SourceLocation LocStart = LSD->getExternLoc();
  if (LocStart.isInvalid())
    llvm_unreachable("Invalid extern SourceLocation");
  
  ReplaceText(LocStart, 0, "// ");
  if (!LSD->hasBraces())
    return;
  // FIXME. We don't rewrite well if '{' is not on same line as 'extern'.
  SourceLocation LocRBrace = LSD->getRBraceLoc();
  if (LocRBrace.isInvalid())
    llvm_unreachable("Invalid rbrace SourceLocation");
  ReplaceText(LocRBrace, 0, "// ");
}

void RewriteModernObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
                                        const FunctionType *&FPRetType) {
  if (T->isObjCQualifiedIdType())
    ResultStr += "id";
  else if (T->isFunctionPointerType() ||
           T->isBlockPointerType()) {
    // needs special handling, since pointer-to-functions have special
    // syntax (where a decaration models use).
    QualType retType = T;
    QualType PointeeTy;
    if (const PointerType* PT = retType->getAs<PointerType>())
      PointeeTy = PT->getPointeeType();
    else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>())
      PointeeTy = BPT->getPointeeType();
    if ((FPRetType = PointeeTy->getAs<FunctionType>())) {
      ResultStr += FPRetType->getResultType().getAsString(
        Context->getPrintingPolicy());
      ResultStr += "(*";
    }
  } else
    ResultStr += T.getAsString(Context->getPrintingPolicy());
}

void RewriteModernObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
                                        ObjCMethodDecl *OMD,
                                        std::string &ResultStr) {
  //fprintf(stderr,"In RewriteObjCMethodDecl\n");
  const FunctionType *FPRetType = 0;
  ResultStr += "\nstatic ";
  RewriteTypeIntoString(OMD->getResultType(), ResultStr, FPRetType);
  ResultStr += " ";

  // Unique method name
  std::string NameStr;

  if (OMD->isInstanceMethod())
    NameStr += "_I_";
  else
    NameStr += "_C_";

  NameStr += IDecl->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(IDecl);
    selfTy = Context->getPointerType(selfTy);
    if (!LangOpts.MicrosoftExt) {
      if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
        ResultStr += "struct ";
    }
    // When rewriting for Microsoft, explicitly omit the structure name.
    ResultStr += IDecl->getNameAsString();
    ResultStr += " *";
  }
  else
    ResultStr += Context->getObjCClassType().getAsString(
      Context->getPrintingPolicy());

  ResultStr += " self, ";
  ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
  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();
      QualType QT = PDecl->getType();
      // Make sure we convert "t (^)(...)" to "t (*)(...)".
      (void)convertBlockPointerToFunctionPointer(QT);
      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
      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(
          Context->getPrintingPolicy());
        ResultStr += ParamStr;
      }
      if (FT->isVariadic()) {
        if (FT->getNumArgs()) ResultStr += ", ";
        ResultStr += "...";
      }
      ResultStr += ")";
    } else {
      ResultStr += "()";
    }
  }
}
void RewriteModernObjC::RewriteImplementationDecl(Decl *OID) {
  ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
  ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);

  if (IMD) {
    if (IMD->getIvarRBraceLoc().isValid()) {
      ReplaceText(IMD->getLocStart(), 1, "/** ");
      ReplaceText(IMD->getIvarRBraceLoc(), 1, "**/ ");
    }
    else {
      InsertText(IMD->getLocStart(), "// ");
    }
  }
  else
    InsertText(CID->getLocStart(), "// ");

  for (ObjCCategoryImplDecl::instmeth_iterator
       I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
       E = IMD ? IMD->instmeth_end() : CID->instmeth_end();
       I != E; ++I) {
    std::string ResultStr;
    ObjCMethodDecl *OMD = *I;
    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
    SourceLocation LocStart = OMD->getLocStart();
    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();

    const char *startBuf = SM->getCharacterData(LocStart);
    const char *endBuf = SM->getCharacterData(LocEnd);
    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
  }

  for (ObjCCategoryImplDecl::classmeth_iterator
       I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(),
       E = IMD ? IMD->classmeth_end() : CID->classmeth_end();
       I != E; ++I) {
    std::string ResultStr;
    ObjCMethodDecl *OMD = *I;
    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
    SourceLocation LocStart = OMD->getLocStart();
    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();

    const char *startBuf = SM->getCharacterData(LocStart);
    const char *endBuf = SM->getCharacterData(LocEnd);
    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
  }
  for (ObjCCategoryImplDecl::propimpl_iterator
       I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
       E = IMD ? IMD->propimpl_end() : CID->propimpl_end();
       I != E; ++I) {
    RewritePropertyImplDecl(*I, IMD, CID);
  }

  InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
}

void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
  // Do not synthesize more than once.
  if (ObjCSynthesizedStructs.count(ClassDecl))
    return;
  // Make sure super class's are written before current class is written.
  ObjCInterfaceDecl *SuperClass = ClassDecl->getSuperClass();
  while (SuperClass) {
    RewriteInterfaceDecl(SuperClass);
    SuperClass = SuperClass->getSuperClass();
  }
  std::string ResultStr;
  if (!ObjCWrittenInterfaces.count(ClassDecl->getCanonicalDecl())) {
    // we haven't seen a forward decl - generate a typedef.
    RewriteOneForwardClassDecl(ClassDecl, ResultStr);
    RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
    
    RewriteObjCInternalStruct(ClassDecl, ResultStr);
    // Mark this typedef as having been written into its c++ equivalent.
    ObjCWrittenInterfaces.insert(ClassDecl->getCanonicalDecl());
  
    for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(),
         E = ClassDecl->prop_end(); I != E; ++I)
      RewriteProperty(*I);
    for (ObjCInterfaceDecl::instmeth_iterator
         I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
         I != E; ++I)
      RewriteMethodDeclaration(*I);
    for (ObjCInterfaceDecl::classmeth_iterator
         I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
         I != E; ++I)
      RewriteMethodDeclaration(*I);

    // Lastly, comment out the @end.
    ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
                "/* @end */");
  }
}

Stmt *RewriteModernObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
  SourceRange OldRange = PseudoOp->getSourceRange();

  // We just magically know some things about the structure of this
  // expression.
  ObjCMessageExpr *OldMsg =
    cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr(
                            PseudoOp->getNumSemanticExprs() - 1));

  // Because the rewriter doesn't allow us to rewrite rewritten code,
  // we need to suppress rewriting the sub-statements.
  Expr *Base;
  SmallVector<Expr*, 2> Args;
  {
    DisableReplaceStmtScope S(*this);

    // Rebuild the base expression if we have one.
    Base = 0;
    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
      Base = OldMsg->getInstanceReceiver();
      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
    }
  
    unsigned numArgs = OldMsg->getNumArgs();
    for (unsigned i = 0; i < numArgs; i++) {
      Expr *Arg = OldMsg->getArg(i);
      if (isa<OpaqueValueExpr>(Arg))
        Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
      Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
      Args.push_back(Arg);
    }
  }

  // TODO: avoid this copy.
  SmallVector<SourceLocation, 1> SelLocs;
  OldMsg->getSelectorLocs(SelLocs);

  ObjCMessageExpr *NewMsg = 0;
  switch (OldMsg->getReceiverKind()) {
  case ObjCMessageExpr::Class:
    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
                                     OldMsg->getValueKind(),
                                     OldMsg->getLeftLoc(),
                                     OldMsg->getClassReceiverTypeInfo(),
                                     OldMsg->getSelector(),
                                     SelLocs,
                                     OldMsg->getMethodDecl(),
                                     Args,
                                     OldMsg->getRightLoc(),
                                     OldMsg->isImplicit());
    break;

  case ObjCMessageExpr::Instance:
    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
                                     OldMsg->getValueKind(),
                                     OldMsg->getLeftLoc(),
                                     Base,
                                     OldMsg->getSelector(),
                                     SelLocs,
                                     OldMsg->getMethodDecl(),
                                     Args,
                                     OldMsg->getRightLoc(),
                                     OldMsg->isImplicit());
    break;

  case ObjCMessageExpr::SuperClass:
  case ObjCMessageExpr::SuperInstance:
    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
                                     OldMsg->getValueKind(),
                                     OldMsg->getLeftLoc(),
                                     OldMsg->getSuperLoc(),
                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
                                     OldMsg->getSuperType(),
                                     OldMsg->getSelector(),
                                     SelLocs,
                                     OldMsg->getMethodDecl(),
                                     Args,
                                     OldMsg->getRightLoc(),
                                     OldMsg->isImplicit());
    break;
  }

  Stmt *Replacement = SynthMessageExpr(NewMsg);
  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
  return Replacement;
}

Stmt *RewriteModernObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) {
  SourceRange OldRange = PseudoOp->getSourceRange();

  // We just magically know some things about the structure of this
  // expression.
  ObjCMessageExpr *OldMsg =
    cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit());

  // Because the rewriter doesn't allow us to rewrite rewritten code,
  // we need to suppress rewriting the sub-statements.
  Expr *Base = 0;
  SmallVector<Expr*, 1> Args;
  {
    DisableReplaceStmtScope S(*this);
    // Rebuild the base expression if we have one.
    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
      Base = OldMsg->getInstanceReceiver();
      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
    }
    unsigned numArgs = OldMsg->getNumArgs();
    for (unsigned i = 0; i < numArgs; i++) {
      Expr *Arg = OldMsg->getArg(i);
      if (isa<OpaqueValueExpr>(Arg))
        Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
      Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
      Args.push_back(Arg);
    }
  }

  // Intentionally empty.
  SmallVector<SourceLocation, 1> SelLocs;

  ObjCMessageExpr *NewMsg = 0;
  switch (OldMsg->getReceiverKind()) {
  case ObjCMessageExpr::Class:
    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
                                     OldMsg->getValueKind(),
                                     OldMsg->getLeftLoc(),
                                     OldMsg->getClassReceiverTypeInfo(),
                                     OldMsg->getSelector(),
                                     SelLocs,
                                     OldMsg->getMethodDecl(),
                                     Args,
                                     OldMsg->getRightLoc(),
                                     OldMsg->isImplicit());
    break;

  case ObjCMessageExpr::Instance:
    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
                                     OldMsg->getValueKind(),
                                     OldMsg->getLeftLoc(),
                                     Base,
                                     OldMsg->getSelector(),
                                     SelLocs,
                                     OldMsg->getMethodDecl(),
                                     Args,
                                     OldMsg->getRightLoc(),
                                     OldMsg->isImplicit());
    break;

  case ObjCMessageExpr::SuperClass:
  case ObjCMessageExpr::SuperInstance:
    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
                                     OldMsg->getValueKind(),
                                     OldMsg->getLeftLoc(),
                                     OldMsg->getSuperLoc(),
                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
                                     OldMsg->getSuperType(),
                                     OldMsg->getSelector(),
                                     SelLocs,
                                     OldMsg->getMethodDecl(),
                                     Args,
                                     OldMsg->getRightLoc(),
                                     OldMsg->isImplicit());
    break;
  }

  Stmt *Replacement = SynthMessageExpr(NewMsg);
  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
  return Replacement;
}

/// 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 *)__rw_items, (unsigned int)16)
///
void RewriteModernObjC::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 *)__rw_items, (unsigned int)16)";
}

/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
/// statement to exit to its outer synthesized loop.
///
Stmt *RewriteModernObjC::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);

  return 0;
}

void RewriteModernObjC::ConvertSourceLocationToLineDirective(
                                          SourceLocation Loc,
                                          std::string &LineString) {
  if (Loc.isFileID()) {
    LineString += "\n#line ";
    PresumedLoc PLoc = SM->getPresumedLoc(Loc);
    LineString += utostr(PLoc.getLine());
    LineString += " \"";
    LineString += Lexer::Stringify(PLoc.getFilename());
    LineString += "\"\n";
  }
}

/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
/// statement to continue with its inner synthesized loop.
///
Stmt *RewriteModernObjC::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);

  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 __rw_items[16];
///   id l_collection = (id)collection;
///   unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
///                                       objects:__rw_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:__rw_items count:16]);
///   elem = nil;
///   __break_label: ;
///  }
///  else
///       elem = nil;
///  }
///
Stmt *RewriteModernObjC::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);
  StringRef elementName;
  std::string elementTypeAsString;
  std::string buf;
  // line directive first.
  SourceLocation ForEachLoc = S->getForLoc();
  ConvertSourceLocationToLineDirective(ForEachLoc, buf);
  buf += "{\n\t";
  if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
    // type elem;
    NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
    QualType ElementType = cast<ValueDecl>(D)->getType();
    if (ElementType->isObjCQualifiedIdType() ||
        ElementType->isObjCQualifiedInterfaceType())
      // Simply use 'id' for all qualified types.
      elementTypeAsString = "id";
    else
      elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy());
    buf += elementTypeAsString;
    buf += " ";
    elementName = D->getName();
    buf += elementName;
    buf += ";\n\t";
  }
  else {
    DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
    elementName = DR->getDecl()->getName();
    ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
    if (VD->getType()->isObjCQualifiedIdType() ||
        VD->getType()->isObjCQualifiedInterfaceType())
      // Simply use 'id' for all qualified types.
      elementTypeAsString = "id";
    else
      elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy());
  }

  // struct __objcFastEnumerationState enumState = { 0 };
  buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
  // id __rw_items[16];
  buf += "id __rw_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);
  // Replace ')' in for '(' type elem in collection ')' with ';'
  SourceLocation rightParenLoc = S->getRParenLoc();
  const char *rparenBuf = SM->getCharacterData(rightParenLoc);
  SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf);
  buf = ";\n\t";

  // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
  //                                   objects:__rw_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 *)__rw_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);

  ///            __continue_label: ;
  ///        } while (counter < limit);
  ///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
  ///                                  objects:__rw_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 += " = ((";
  buf += elementTypeAsString;
  buf += ")0);\n\t";
  buf += "__break_label_";
  buf += utostr(ObjCBcLabelNo.back());
  buf += ": ;\n\t";
  buf += "}\n\t";
  buf += "else\n\t\t";
  buf += elementName;
  buf += " = ((";
  buf += elementTypeAsString;
  buf += ")0);\n\t";
  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.getLocWithOffset(1);
    InsertText(endBodyLoc, buf);
  } 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.getLocWithOffset(semiBuf-stmtBuf+1);
    InsertText(endBodyLoc, buf);
  }
  Stmts.pop_back();
  ObjCBcLabelNo.pop_back();
  return 0;
}

static void Write_RethrowObject(std::string &buf) {
  buf += "{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
  buf += "\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
  buf += "\tid rethrow;\n";
  buf += "\t} _fin_force_rethow(_rethrow);";
}

/// RewriteObjCSynchronizedStmt -
/// This routine rewrites @synchronized(expr) stmt;
/// into:
/// objc_sync_enter(expr);
/// @try stmt @finally { objc_sync_exit(expr); }
///
Stmt *RewriteModernObjC::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;
  SourceLocation SynchLoc = S->getAtSynchronizedLoc();
  ConvertSourceLocationToLineDirective(SynchLoc, buf);
  buf += "{ id _rethrow = 0; id _sync_obj = ";
  
  const char *lparenBuf = startBuf;
  while (*lparenBuf != '(') lparenBuf++;
  ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
  
  buf = "; objc_sync_enter(_sync_obj);\n";
  buf += "try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
  buf += "\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
  buf += "\n\tid sync_exit;";
  buf += "\n\t} _sync_exit(_sync_obj);\n";

  // 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 RParenExprLoc = S->getSynchBody()->getLocStart();
  const char *RParenExprLocBuf = SM->getCharacterData(RParenExprLoc);
  while (*RParenExprLocBuf != ')') RParenExprLocBuf--;
  RParenExprLoc = startLoc.getLocWithOffset(RParenExprLocBuf-startBuf);
  
  SourceLocation LBranceLoc = S->getSynchBody()->getLocStart();
  const char *LBraceLocBuf = SM->getCharacterData(LBranceLoc);
  assert (*LBraceLocBuf == '{');
  ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->getCharacterData(RParenExprLoc) + 1), buf);
  
  SourceLocation startRBraceLoc = S->getSynchBody()->getLocEnd();
  assert((*SM->getCharacterData(startRBraceLoc) == '}') &&
         "bogus @synchronized block");
  
  buf = "} catch (id e) {_rethrow = e;}\n";
  Write_RethrowObject(buf);
  buf += "}\n";
  buf += "}\n";

  ReplaceText(startRBraceLoc, 1, buf);

  return 0;
}

void RewriteModernObjC::WarnAboutReturnGotoStmts(Stmt *S)
{
  // Perform a bottom up traversal of all children.
  for (Stmt::child_range CI = S->children(); CI; ++CI)
    if (*CI)
      WarnAboutReturnGotoStmts(*CI);

  if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
    Diags.Report(Context->getFullLoc(S->getLocStart()),
                 TryFinallyContainsReturnDiag);
  }
  return;
}

Stmt *RewriteModernObjC::RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt  *S) {
  SourceLocation startLoc = S->getAtLoc();
  ReplaceText(startLoc, strlen("@autoreleasepool"), "/* @autoreleasepool */");
  ReplaceText(S->getSubStmt()->getLocStart(), 1, 
              "{ __AtAutoreleasePool __autoreleasepool; ");
  
  return 0;
}

Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
  ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt();
  bool noCatch = S->getNumCatchStmts() == 0;
  std::string buf;
  SourceLocation TryLocation = S->getAtTryLoc();
  ConvertSourceLocationToLineDirective(TryLocation, buf);
  
  if (finalStmt) {
    if (noCatch)
      buf += "{ id volatile _rethrow = 0;\n";
    else {
      buf += "{ id volatile _rethrow = 0;\ntry {\n";
    }
  }
  // Get the start location and compute the semi location.
  SourceLocation startLoc = S->getLocStart();
  const char *startBuf = SM->getCharacterData(startLoc);

  assert((*startBuf == '@') && "bogus @try location");
  if (finalStmt)
    ReplaceText(startLoc, 1, buf);
  else
    // @try -> try
    ReplaceText(startLoc, 1, "");
  
  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
    ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
    VarDecl *catchDecl = Catch->getCatchParamDecl();
    
    startLoc = Catch->getLocStart();
    bool AtRemoved = false;
    if (catchDecl) {
      QualType t = catchDecl->getType();
      if (const ObjCObjectPointerType *Ptr = t->getAs<ObjCObjectPointerType>()) {
        // Should be a pointer to a class.
        ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
        if (IDecl) {
          std::string Result;
          ConvertSourceLocationToLineDirective(Catch->getLocStart(), Result);
          
          startBuf = SM->getCharacterData(startLoc);
          assert((*startBuf == '@') && "bogus @catch location");
          SourceLocation rParenLoc = Catch->getRParenLoc();
          const char *rParenBuf = SM->getCharacterData(rParenLoc);
          
          // _objc_exc_Foo *_e as argument to catch.
          Result += "catch (_objc_exc_"; Result += IDecl->getNameAsString();
          Result += " *_"; Result += catchDecl->getNameAsString();
          Result += ")";
          ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
          // Foo *e = (Foo *)_e;
          Result.clear();
          Result = "{ ";
          Result += IDecl->getNameAsString();
          Result += " *"; Result += catchDecl->getNameAsString();
          Result += " = ("; Result += IDecl->getNameAsString(); Result += "*)";
          Result += "_"; Result += catchDecl->getNameAsString();
          
          Result += "; ";
          SourceLocation lBraceLoc = Catch->getCatchBody()->getLocStart();
          ReplaceText(lBraceLoc, 1, Result);
          AtRemoved = true;
        }
      }
    }
    if (!AtRemoved)
      // @catch -> catch
      ReplaceText(startLoc, 1, "");
      
  }
  if (finalStmt) {
    buf.clear();
    SourceLocation FinallyLoc = finalStmt->getLocStart();
    
    if (noCatch) {
      ConvertSourceLocationToLineDirective(FinallyLoc, buf);
      buf += "catch (id e) {_rethrow = e;}\n";
    }
    else {
      buf += "}\n";
      ConvertSourceLocationToLineDirective(FinallyLoc, buf);
      buf += "catch (id e) {_rethrow = e;}\n";
    }
    
    SourceLocation startFinalLoc = finalStmt->getLocStart();
    ReplaceText(startFinalLoc, 8, buf);
    Stmt *body = finalStmt->getFinallyBody();
    SourceLocation startFinalBodyLoc = body->getLocStart();
    buf.clear();
    Write_RethrowObject(buf);
    ReplaceText(startFinalBodyLoc, 1, buf);
    
    SourceLocation endFinalBodyLoc = body->getLocEnd();
    ReplaceText(endFinalBodyLoc, 1, "}\n}");
    // Now check for any return/continue/go statements within the @try.
    WarnAboutReturnGotoStmts(S->getTryBody());
  }

  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 *RewriteModernObjC::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
    buf = "throw";

  // handle "@  throw" correctly.
  const char *wBuf = strchr(startBuf, 'w');
  assert((*wBuf == 'w') && "@throw: can't find 'w'");
  ReplaceText(startLoc, wBuf-startBuf+1, buf);

  const char *semiBuf = strchr(startBuf, ';');
  assert((*semiBuf == ';') && "@throw: can't find ';'");
  SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf);
  if (S->getThrowExpr())
    ReplaceText(semiLoc, 1, ");");
  return 0;
}

Stmt *RewriteModernObjC::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,
                                            StringLiteral::Ascii, false,
                                            StrType, SourceLocation());
  ReplaceStmt(Exp, Replacement);

  // Replace this subexpr in the parent.
  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
  return Replacement;
}

Stmt *RewriteModernObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
  if (!SelGetUidFunctionDecl)
    SynthSelGetUidFunctionDecl();
  assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
  // Create a call to sel_registerName("selName").
  SmallVector<Expr*, 8> SelExprs;
  QualType argType = Context->getPointerType(Context->CharTy);
  SelExprs.push_back(StringLiteral::Create(*Context,
                                           Exp->getSelector().getAsString(),
                                           StringLiteral::Ascii, false,
                                           argType, SourceLocation()));
  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
                                                 &SelExprs[0], SelExprs.size());
  ReplaceStmt(Exp, SelExp);
  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
  return SelExp;
}

CallExpr *RewriteModernObjC::SynthesizeCallToFunctionDecl(
  FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
                                                    SourceLocation EndLoc) {
  // 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, false, msgSendType, VK_LValue, SourceLocation());

  // Now, we cast the reference to a pointer to the objc_msgSend type.
  QualType pToFunc = Context->getPointerType(msgSendType);
  ImplicitCastExpr *ICE = 
    ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
                             DRE, 0, VK_RValue);

  const FunctionType *FT = msgSendType->getAs<FunctionType>();

  CallExpr *Exp =  
    new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs),
                           FT->getCallResultType(*Context),
                           VK_RValue, EndLoc);
  return Exp;
}

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 RewriteModernObjC::needToScanForQualifiers(QualType T) {
  if (T->isObjCQualifiedIdType())
    return true;
  if (const PointerType *PT = T->getAs<PointerType>()) {
    if (PT->getPointeeType()->isObjCQualifiedIdType())
      return true;
  }
  if (T->isObjCObjectPointerType()) {
    T = T->getPointeeType();
    return T->isObjCQualifiedInterfaceType();
  }
  if (T->isArrayType()) {
    QualType ElemTy = Context->getBaseElementType(T);
    return needToScanForQualifiers(ElemTy);
  }
  return false;
}

void RewriteModernObjC::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.getLocWithOffset(startRef-startBuf);
      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1);
      // Comment out the protocol references.
      InsertText(LessLoc, "/*");
      InsertText(GreaterLoc, "*/");
    }
  }
}

void RewriteModernObjC::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()->getAs<FunctionType>();
    assert(funcType && "missing function type");
    proto = dyn_cast<FunctionProtoType>(funcType);
    if (!proto)
      return;
    Type = proto->getResultType();
  }
  else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
    Loc = FD->getLocation();
    Type = FD->getType();
  }
  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.getLocWithOffset(startRef-endBuf);
      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1);
      // Comment out the protocol references.
      InsertText(LessLoc, "/*");
      InsertText(GreaterLoc, "*/");
    }
  }
  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.getLocWithOffset(startRef-startFuncBuf);
        SourceLocation GreaterLoc =
          Loc.getLocWithOffset(endRef-startFuncBuf+1);
        // Comment out the protocol references.
        InsertText(LessLoc, "/*");
        InsertText(GreaterLoc, "*/");
      }
      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++;
    }
  }
}

void RewriteModernObjC::RewriteTypeOfDecl(VarDecl *ND) {
  QualType QT = ND->getType();
  const Type* TypePtr = QT->getAs<Type>();
  if (!isa<TypeOfExprType>(TypePtr))
    return;
  while (isa<TypeOfExprType>(TypePtr)) {
    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
    TypePtr = QT->getAs<Type>();
  }
  // FIXME. This will not work for multiple declarators; as in:
  // __typeof__(a) b,c,d;
  std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy()));
  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
  const char *startBuf = SM->getCharacterData(DeclLoc);
  if (ND->getInit()) {
    std::string Name(ND->getNameAsString());
    TypeAsString += " " + Name + " = ";
    Expr *E = ND->getInit();
    SourceLocation startLoc;
    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
      startLoc = ECE->getLParenLoc();
    else
      startLoc = E->getLocStart();
    startLoc = SM->getExpansionLoc(startLoc);
    const char *endBuf = SM->getCharacterData(startLoc);
    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
  }
  else {
    SourceLocation X = ND->getLocEnd();
    X = SM->getExpansionLoc(X);
    const char *endBuf = SM->getCharacterData(X);
    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
  }
}

// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
  IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
  SmallVector<QualType, 16> ArgTys;
  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
  QualType getFuncType =
    getSimpleFunctionType(Context->getObjCSelType(), &ArgTys[0], ArgTys.size());
  SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
                                           SourceLocation(),
                                           SourceLocation(),
                                           SelGetUidIdent, getFuncType, 0,
                                           SC_Extern,
                                           SC_None, false);
}

void RewriteModernObjC::RewriteFunctionDecl(FunctionDecl *FD) {
  // declared in <objc/objc.h>
  if (FD->getIdentifier() &&
      FD->getName() == "sel_registerName") {
    SelGetUidFunctionDecl = FD;
    return;
  }
  RewriteObjCQualifiedInterfaceTypes(FD);
}

void RewriteModernObjC::RewriteBlockPointerType(std::string& Str, QualType Type) {
  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
  const char *argPtr = TypeString.c_str();
  if (!strchr(argPtr, '^')) {
    Str += TypeString;
    return;
  }
  while (*argPtr) {
    Str += (*argPtr == '^' ? '*' : *argPtr);
    argPtr++;
  }
}

// FIXME. Consolidate this routine with RewriteBlockPointerType.
void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
                                                  ValueDecl *VD) {
  QualType Type = VD->getType();
  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
  const char *argPtr = TypeString.c_str();
  int paren = 0;
  while (*argPtr) {
    switch (*argPtr) {
      case '(':
        Str += *argPtr;
        paren++;
        break;
      case ')':
        Str += *argPtr;
        paren--;
        break;
      case '^':
        Str += '*';
        if (paren == 1)
          Str += VD->getNameAsString();
        break;
      default:
        Str += *argPtr;
        break;
    }
    argPtr++;
  }
}

void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
  const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
  const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType);
  if (!proto)
    return;
  QualType Type = proto->getResultType();
  std::string FdStr = Type.getAsString(Context->getPrintingPolicy());
  FdStr += " ";
  FdStr += FD->getName();
  FdStr +=  "(";
  unsigned numArgs = proto->getNumArgs();
  for (unsigned i = 0; i < numArgs; i++) {
  QualType ArgType = proto->getArgType(i);
  RewriteBlockPointerType(FdStr, ArgType);
  if (i+1 < numArgs)
    FdStr += ", ";
  }
  if (FD->isVariadic()) {
    FdStr +=  (numArgs > 0) ? ", ...);\n" : "...);\n";
  }
  else
    FdStr +=  ");\n";
  InsertText(FunLocStart, FdStr);
}

// SynthSuperContructorFunctionDecl - id __rw_objc_super(id obj, id super);
void RewriteModernObjC::SynthSuperContructorFunctionDecl() {
  if (SuperContructorFunctionDecl)
    return;
  IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super");
  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 = getSimpleFunctionType(Context->getObjCIdType(),
                                               &ArgTys[0], ArgTys.size());
  SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
                                         SourceLocation(),
                                         SourceLocation(),
                                         msgSendIdent, msgSendType, 0,
                                         SC_Extern,
                                         SC_None, false);
}

// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
void RewriteModernObjC::SynthMsgSendFunctionDecl() {
  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
  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 = getSimpleFunctionType(Context->getObjCIdType(),
                                               &ArgTys[0], ArgTys.size(),
                                               true /*isVariadic*/);
  MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
                                         SourceLocation(),
                                         SourceLocation(),
                                         msgSendIdent, msgSendType, 0,
                                         SC_Extern,
                                         SC_None, false);
}

// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(void);
void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
  SmallVector<QualType, 2> ArgTys;
  ArgTys.push_back(Context->VoidTy);
  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
                                               &ArgTys[0], 1,
                                               true /*isVariadic*/);
  MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
                                              SourceLocation(),
                                              SourceLocation(),
                                              msgSendIdent, msgSendType, 0,
                                              SC_Extern,
                                              SC_None, false);
}

// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
  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 = getSimpleFunctionType(Context->getObjCIdType(),
                                               &ArgTys[0], ArgTys.size(),
                                               true /*isVariadic*/);
  MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
                                         SourceLocation(),
                                         SourceLocation(),
                                         msgSendIdent, msgSendType, 0,
                                         SC_Extern,
                                         SC_None, false);
}

// SynthMsgSendSuperStretFunctionDecl -
// id objc_msgSendSuper_stret(void);
void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
  IdentifierInfo *msgSendIdent =
    &Context->Idents.get("objc_msgSendSuper_stret");
  SmallVector<QualType, 2> ArgTys;
  ArgTys.push_back(Context->VoidTy);
  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
                                               &ArgTys[0], 1,
                                               true /*isVariadic*/);
  MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
                                                       SourceLocation(),
                                                       SourceLocation(),
                                              msgSendIdent, msgSendType, 0,
                                              SC_Extern,
                                              SC_None, false);
}

// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
  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 = getSimpleFunctionType(Context->DoubleTy,
                                               &ArgTys[0], ArgTys.size(),
                                               true /*isVariadic*/);
  MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
                                              SourceLocation(),
                                              SourceLocation(),
                                              msgSendIdent, msgSendType, 0,
                                              SC_Extern,
                                              SC_None, false);
}

// SynthGetClassFunctionDecl - Class objc_getClass(const char *name);
void RewriteModernObjC::SynthGetClassFunctionDecl() {
  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
  SmallVector<QualType, 16> ArgTys;
  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
                                                &ArgTys[0], ArgTys.size());
  GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
                                          SourceLocation(),
                                          SourceLocation(),
                                          getClassIdent, getClassType, 0,
                                          SC_Extern,
                                          SC_None, false);
}

// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
  IdentifierInfo *getSuperClassIdent = 
    &Context->Idents.get("class_getSuperclass");
  SmallVector<QualType, 16> ArgTys;
  ArgTys.push_back(Context->getObjCClassType());
  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
                                                &ArgTys[0], ArgTys.size());
  GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
                                                   SourceLocation(),
                                                   SourceLocation(),
                                                   getSuperClassIdent,
                                                   getClassType, 0,
                                                   SC_Extern,
                                                   SC_None,
                                                   false);
}

// SynthGetMetaClassFunctionDecl - Class objc_getMetaClass(const char *name);
void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
  SmallVector<QualType, 16> ArgTys;
  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
                                                &ArgTys[0], ArgTys.size());
  GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
                                              SourceLocation(),
                                              SourceLocation(),
                                              getClassIdent, getClassType, 0,
                                              SC_Extern,
                                              SC_None, false);
}

Stmt *RewriteModernObjC::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, 0, PrintingPolicy(LangOpts));
  Preamble += prettyBuf.str();
  Preamble += ",";
  Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";

  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
                                   SourceLocation(), &Context->Idents.get(S),
                                   strType, 0, SC_Static, SC_None);
  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
                                               SourceLocation());
  Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
                                 Context->getPointerType(DRE->getType()),
                                           VK_RValue, OK_Ordinary,
                                           SourceLocation());
  // cast to NSConstantString *
  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
                                            CK_CPointerToObjCPointerCast, Unop);
  ReplaceStmt(Exp, cast);
  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
  return cast;
}

Stmt *RewriteModernObjC::RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp) {
  unsigned IntSize =
    static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
  
  Expr *FlagExp = IntegerLiteral::Create(*Context, 
                                         llvm::APInt(IntSize, Exp->getValue()), 
                                         Context->IntTy, Exp->getLocation());
  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
                                            CK_BitCast, FlagExp);
  ParenExpr *PE = new (Context) ParenExpr(Exp->getLocation(), Exp->getExprLoc(), 
                                          cast);
  ReplaceStmt(Exp, PE);
  return PE;
}

Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) {
  // synthesize declaration of helper functions needed in this routine.
  if (!SelGetUidFunctionDecl)
    SynthSelGetUidFunctionDecl();
  // use objc_msgSend() for all.
  if (!MsgSendFunctionDecl)
    SynthMsgSendFunctionDecl();
  if (!GetClassFunctionDecl)
    SynthGetClassFunctionDecl();
  
  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
  SourceLocation StartLoc = Exp->getLocStart();
  SourceLocation EndLoc = Exp->getLocEnd();
  
  // Synthesize a call to objc_msgSend().
  SmallVector<Expr*, 4> MsgExprs;
  SmallVector<Expr*, 4> ClsExprs;
  QualType argType = Context->getPointerType(Context->CharTy);
  
  // Create a call to objc_getClass("<BoxingClass>"). It will be the 1st argument.
  ObjCMethodDecl *BoxingMethod = Exp->getBoxingMethod();
  ObjCInterfaceDecl *BoxingClass = BoxingMethod->getClassInterface();
  
  IdentifierInfo *clsName = BoxingClass->getIdentifier();
  ClsExprs.push_back(StringLiteral::Create(*Context,
                                           clsName->getName(),
                                           StringLiteral::Ascii, false,
                                           argType, SourceLocation()));
  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
                                               &ClsExprs[0],
                                               ClsExprs.size(), 
                                               StartLoc, EndLoc);
  MsgExprs.push_back(Cls);
  
  // Create a call to sel_registerName("<BoxingMethod>:"), etc.
  // it will be the 2nd argument.
  SmallVector<Expr*, 4> SelExprs;
  SelExprs.push_back(StringLiteral::Create(*Context,
                                           BoxingMethod->getSelector().getAsString(),
                                           StringLiteral::Ascii, false,
                                           argType, SourceLocation()));
  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
                                                  &SelExprs[0], SelExprs.size(),
                                                  StartLoc, EndLoc);
  MsgExprs.push_back(SelExp);
  
  // User provided sub-expression is the 3rd, and last, argument.
  Expr *subExpr  = Exp->getSubExpr();
  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(subExpr)) {
    QualType type = ICE->getType();
    const Expr *SubExpr = ICE->IgnoreParenImpCasts();
    CastKind CK = CK_BitCast;
    if (SubExpr->getType()->isIntegralType(*Context) && type->isBooleanType())
      CK = CK_IntegralToBoolean;
    subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
  }
  MsgExprs.push_back(subExpr);
  
  SmallVector<QualType, 4> ArgTypes;
  ArgTypes.push_back(Context->getObjCIdType());
  ArgTypes.push_back(Context->getObjCSelType());
  for (ObjCMethodDecl::param_iterator PI = BoxingMethod->param_begin(),
       E = BoxingMethod->param_end(); PI != E; ++PI)
    ArgTypes.push_back((*PI)->getType());
  
  QualType returnType = Exp->getType();
  // 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, false, msgSendType,
                                               VK_LValue, SourceLocation());
  
  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
                                            Context->getPointerType(Context->VoidTy),
                                            CK_BitCast, DRE);
  
  // Now do the "normal" pointer to function cast.
  QualType castType =
  getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
                        BoxingMethod->isVariadic());
  castType = Context->getPointerType(castType);
  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
                                  cast);
  
  // Don't forget the parens to enforce the proper binding.
  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
  
  const FunctionType *FT = msgSendType->getAs<FunctionType>();
  CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs,
                                        FT->getResultType(), VK_RValue,
                                        EndLoc);
  ReplaceStmt(Exp, CE);
  return CE;
}

Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
  // synthesize declaration of helper functions needed in this routine.
  if (!SelGetUidFunctionDecl)
    SynthSelGetUidFunctionDecl();
  // use objc_msgSend() for all.
  if (!MsgSendFunctionDecl)
    SynthMsgSendFunctionDecl();
  if (!GetClassFunctionDecl)
    SynthGetClassFunctionDecl();
  
  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
  SourceLocation StartLoc = Exp->getLocStart();
  SourceLocation EndLoc = Exp->getLocEnd();
  
  // Build the expression: __NSContainer_literal(int, ...).arr
  QualType IntQT = Context->IntTy;
  QualType NSArrayFType =
    getSimpleFunctionType(Context->VoidTy, &IntQT, 1, true);
  std::string NSArrayFName("__NSContainer_literal");
  FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
  DeclRefExpr *NSArrayDRE = 
    new (Context) DeclRefExpr(NSArrayFD, false, NSArrayFType, VK_RValue,
                              SourceLocation());

  SmallVector<Expr*, 16> InitExprs;
  unsigned NumElements = Exp->getNumElements();
  unsigned UnsignedIntSize = 
    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
  Expr *count = IntegerLiteral::Create(*Context,
                                       llvm::APInt(UnsignedIntSize, NumElements),
                                       Context->UnsignedIntTy, SourceLocation());
  InitExprs.push_back(count);
  for (unsigned i = 0; i < NumElements; i++)
    InitExprs.push_back(Exp->getElement(i));
  Expr *NSArrayCallExpr = 
    new (Context) CallExpr(*Context, NSArrayDRE, InitExprs,
                           NSArrayFType, VK_LValue, SourceLocation());
  
  FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(),
                                    SourceLocation(),
                                    &Context->Idents.get("arr"),
                                    Context->getPointerType(Context->VoidPtrTy), 0,
                                    /*BitWidth=*/0, /*Mutable=*/true,
                                    ICIS_NoInit);
  MemberExpr *ArrayLiteralME = 
    new (Context) MemberExpr(NSArrayCallExpr, false, ARRFD, 
                             SourceLocation(),
                             ARRFD->getType(), VK_LValue,
                             OK_Ordinary);
  QualType ConstIdT = Context->getObjCIdType().withConst();
  CStyleCastExpr * ArrayLiteralObjects = 
    NoTypeInfoCStyleCastExpr(Context, 
                             Context->getPointerType(ConstIdT),
                             CK_BitCast,
                             ArrayLiteralME);
  
  // Synthesize a call to objc_msgSend().
  SmallVector<Expr*, 32> MsgExprs;
  SmallVector<Expr*, 4> ClsExprs;
  QualType argType = Context->getPointerType(Context->CharTy);
  QualType expType = Exp->getType();
  
  // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
  ObjCInterfaceDecl *Class = 
    expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
  
  IdentifierInfo *clsName = Class->getIdentifier();
  ClsExprs.push_back(StringLiteral::Create(*Context,
                                           clsName->getName(),
                                           StringLiteral::Ascii, false,
                                           argType, SourceLocation()));
  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
                                               &ClsExprs[0],
                                               ClsExprs.size(), 
                                               StartLoc, EndLoc);
  MsgExprs.push_back(Cls);
  
  // Create a call to sel_registerName("arrayWithObjects:count:").
  // it will be the 2nd argument.
  SmallVector<Expr*, 4> SelExprs;
  ObjCMethodDecl *ArrayMethod = Exp->getArrayWithObjectsMethod();
  SelExprs.push_back(StringLiteral::Create(*Context,
                                           ArrayMethod->getSelector().getAsString(),
                                           StringLiteral::Ascii, false,
                                           argType, SourceLocation()));
  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
                                                  &SelExprs[0], SelExprs.size(),
                                                  StartLoc, EndLoc);
  MsgExprs.push_back(SelExp);
  
  // (const id [])objects
  MsgExprs.push_back(ArrayLiteralObjects);
  
  // (NSUInteger)cnt
  Expr *cnt = IntegerLiteral::Create(*Context,
                                     llvm::APInt(UnsignedIntSize, NumElements),
                                     Context->UnsignedIntTy, SourceLocation());
  MsgExprs.push_back(cnt);
  
  
  SmallVector<QualType, 4> ArgTypes;
  ArgTypes.push_back(Context->getObjCIdType());
  ArgTypes.push_back(Context->getObjCSelType());
  for (ObjCMethodDecl::param_iterator PI = ArrayMethod->param_begin(),
       E = ArrayMethod->param_end(); PI != E; ++PI)
    ArgTypes.push_back((*PI)->getType());
  
  QualType returnType = Exp->getType();
  // 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, false, msgSendType,
                                               VK_LValue, SourceLocation());
  
  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
                                            Context->getPointerType(Context->VoidTy),
                                            CK_BitCast, DRE);
  
  // Now do the "normal" pointer to function cast.
  QualType castType =
  getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
                        ArrayMethod->isVariadic());
  castType = Context->getPointerType(castType);
  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
                                  cast);
  
  // Don't forget the parens to enforce the proper binding.
  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
  
  const FunctionType *FT = msgSendType->getAs<FunctionType>();
  CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs,
                                        FT->getResultType(), VK_RValue,
                                        EndLoc);
  ReplaceStmt(Exp, CE);
  return CE;
}

Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp) {
  // synthesize declaration of helper functions needed in this routine.
  if (!SelGetUidFunctionDecl)
    SynthSelGetUidFunctionDecl();
  // use objc_msgSend() for all.
  if (!MsgSendFunctionDecl)
    SynthMsgSendFunctionDecl();
  if (!GetClassFunctionDecl)
    SynthGetClassFunctionDecl();
  
  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
  SourceLocation StartLoc = Exp->getLocStart();
  SourceLocation EndLoc = Exp->getLocEnd();
  
  // Build the expression: __NSContainer_literal(int, ...).arr
  QualType IntQT = Context->IntTy;
  QualType NSDictFType =
    getSimpleFunctionType(Context->VoidTy, &IntQT, 1, true);
  std::string NSDictFName("__NSContainer_literal");
  FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
  DeclRefExpr *NSDictDRE = 
    new (Context) DeclRefExpr(NSDictFD, false, NSDictFType, VK_RValue,
                              SourceLocation());
  
  SmallVector<Expr*, 16> KeyExprs;
  SmallVector<Expr*, 16> ValueExprs;
  
  unsigned NumElements = Exp->getNumElements();
  unsigned UnsignedIntSize = 
    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
  Expr *count = IntegerLiteral::Create(*Context,
                                       llvm::APInt(UnsignedIntSize, NumElements),
                                       Context->UnsignedIntTy, SourceLocation());
  KeyExprs.push_back(count);
  ValueExprs.push_back(count);
  for (unsigned i = 0; i < NumElements; i++) {
    ObjCDictionaryElement Element = Exp->getKeyValueElement(i);
    KeyExprs.push_back(Element.Key);
    ValueExprs.push_back(Element.Value);
  }
  
  // (const id [])objects
  Expr *NSValueCallExpr = 
    new (Context) CallExpr(*Context, NSDictDRE, ValueExprs,
                           NSDictFType, VK_LValue, SourceLocation());
  
  FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(),
                                       SourceLocation(),
                                       &Context->Idents.get("arr"),
                                       Context->getPointerType(Context->VoidPtrTy), 0,
                                       /*BitWidth=*/0, /*Mutable=*/true,
                                       ICIS_NoInit);
  MemberExpr *DictLiteralValueME = 
    new (Context) MemberExpr(NSValueCallExpr, false, ARRFD, 
                             SourceLocation(),
                             ARRFD->getType(), VK_LValue,
                             OK_Ordinary);
  QualType ConstIdT = Context->getObjCIdType().withConst();
  CStyleCastExpr * DictValueObjects = 
    NoTypeInfoCStyleCastExpr(Context, 
                             Context->getPointerType(ConstIdT),
                             CK_BitCast,
                             DictLiteralValueME);
  // (const id <NSCopying> [])keys
  Expr *NSKeyCallExpr = 
    new (Context) CallExpr(*Context, NSDictDRE, KeyExprs,
                           NSDictFType, VK_LValue, SourceLocation());
  
  MemberExpr *DictLiteralKeyME = 
    new (Context) MemberExpr(NSKeyCallExpr, false, ARRFD, 
                             SourceLocation(),
                             ARRFD->getType(), VK_LValue,
                             OK_Ordinary);
  
  CStyleCastExpr * DictKeyObjects = 
    NoTypeInfoCStyleCastExpr(Context, 
                             Context->getPointerType(ConstIdT),
                             CK_BitCast,
                             DictLiteralKeyME);
  
  
  
  // Synthesize a call to objc_msgSend().
  SmallVector<Expr*, 32> MsgExprs;
  SmallVector<Expr*, 4> ClsExprs;
  QualType argType = Context->getPointerType(Context->CharTy);
  QualType expType = Exp->getType();
  
  // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
  ObjCInterfaceDecl *Class = 
  expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
  
  IdentifierInfo *clsName = Class->getIdentifier();
  ClsExprs.push_back(StringLiteral::Create(*Context,
                                           clsName->getName(),
                                           StringLiteral::Ascii, false,
                                           argType, SourceLocation()));
  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
                                               &ClsExprs[0],
                                               ClsExprs.size(), 
                                               StartLoc, EndLoc);
  MsgExprs.push_back(Cls);
  
  // Create a call to sel_registerName("arrayWithObjects:count:").
  // it will be the 2nd argument.
  SmallVector<Expr*, 4> SelExprs;
  ObjCMethodDecl *DictMethod = Exp->getDictWithObjectsMethod();
  SelExprs.push_back(StringLiteral::Create(*Context,
                                           DictMethod->getSelector().getAsString(),
                                           StringLiteral::Ascii, false,
                                           argType, SourceLocation()));
  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
                                                  &SelExprs[0], SelExprs.size(),
                                                  StartLoc, EndLoc);
  MsgExprs.push_back(SelExp);
  
  // (const id [])objects
  MsgExprs.push_back(DictValueObjects);
  
  // (const id <NSCopying> [])keys
  MsgExprs.push_back(DictKeyObjects);
  
  // (NSUInteger)cnt
  Expr *cnt = IntegerLiteral::Create(*Context,
                                     llvm::APInt(UnsignedIntSize, NumElements),
                                     Context->UnsignedIntTy, SourceLocation());
  MsgExprs.push_back(cnt);
  
  
  SmallVector<QualType, 8> ArgTypes;
  ArgTypes.push_back(Context->getObjCIdType());
  ArgTypes.push_back(Context->getObjCSelType());
  for (ObjCMethodDecl::param_iterator PI = DictMethod->param_begin(),
       E = DictMethod->param_end(); PI != E; ++PI) {
    QualType T = (*PI)->getType();
    if (const PointerType* PT = T->getAs<PointerType>()) {
      QualType PointeeTy = PT->getPointeeType();
      convertToUnqualifiedObjCType(PointeeTy);
      T = Context->getPointerType(PointeeTy);
    }
    ArgTypes.push_back(T);
  }
  
  QualType returnType = Exp->getType();
  // 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, false, msgSendType,
                                               VK_LValue, SourceLocation());
  
  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
                                            Context->getPointerType(Context->VoidTy),
                                            CK_BitCast, DRE);
  
  // Now do the "normal" pointer to function cast.
  QualType castType =
  getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
                        DictMethod->isVariadic());
  castType = Context->getPointerType(castType);
  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
                                  cast);
  
  // Don't forget the parens to enforce the proper binding.
  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
  
  const FunctionType *FT = msgSendType->getAs<FunctionType>();
  CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs,
                                        FT->getResultType(), VK_RValue,
                                        EndLoc);
  ReplaceStmt(Exp, CE);
  return CE;
}

// struct __rw_objc_super { 
//   struct objc_object *object; struct objc_object *superClass; 
// };
QualType RewriteModernObjC::getSuperStructType() {
  if (!SuperStructDecl) {
    SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                         SourceLocation(), SourceLocation(),
                                         &Context->Idents.get("__rw_objc_super"));
    QualType FieldTypes[2];

    // struct objc_object *object;
    FieldTypes[0] = Context->getObjCIdType();
    // struct objc_object *superClass;
    FieldTypes[1] = Context->getObjCIdType();

    // Create fields
    for (unsigned i = 0; i < 2; ++i) {
      SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
                                                 SourceLocation(),
                                                 SourceLocation(), 0,
                                                 FieldTypes[i], 0,
                                                 /*BitWidth=*/0,
                                                 /*Mutable=*/false,
                                                 ICIS_NoInit));
    }

    SuperStructDecl->completeDefinition();
  }
  return Context->getTagDeclType(SuperStructDecl);
}

QualType RewriteModernObjC::getConstantStringStructType() {
  if (!ConstantStringDecl) {
    ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                            SourceLocation(), 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(FieldDecl::Create(*Context,
                                                    ConstantStringDecl,
                                                    SourceLocation(),
                                                    SourceLocation(), 0,
                                                    FieldTypes[i], 0,
                                                    /*BitWidth=*/0,
                                                    /*Mutable=*/true,
                                                    ICIS_NoInit));
    }

    ConstantStringDecl->completeDefinition();
  }
  return Context->getTagDeclType(ConstantStringDecl);
}

/// getFunctionSourceLocation - returns start location of a function
/// definition. Complication arises when function has declared as
/// extern "C" or extern "C" {...}
static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
                                                 FunctionDecl *FD) {
  if (FD->isExternC()  && !FD->isMain()) {
    const DeclContext *DC = FD->getDeclContext();
    if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC))
      // if it is extern "C" {...}, return function decl's own location.
      if (!LSD->getRBraceLoc().isValid())
        return LSD->getExternLoc();
  }
  if (FD->getStorageClassAsWritten() != SC_None)
    R.RewriteBlockLiteralFunctionDecl(FD);
  return FD->getTypeSpecStartLoc();
}

void RewriteModernObjC::RewriteLineDirective(const Decl *D) {
  
  SourceLocation Location = D->getLocation();
  
  if (Location.isFileID()) {
    std::string LineString("\n#line ");
    PresumedLoc PLoc = SM->getPresumedLoc(Location);
    LineString += utostr(PLoc.getLine());
    LineString += " \"";
    LineString += Lexer::Stringify(PLoc.getFilename());
    if (isa<ObjCMethodDecl>(D))
      LineString += "\"";
    else LineString += "\"\n";
    
    Location = D->getLocStart();
    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
      if (FD->isExternC()  && !FD->isMain()) {
        const DeclContext *DC = FD->getDeclContext();
        if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC))
          // if it is extern "C" {...}, return function decl's own location.
          if (!LSD->getRBraceLoc().isValid())
            Location = LSD->getExternLoc();
      }
    }
    InsertText(Location, LineString);
  }
}

/// SynthMsgSendStretCallExpr - This routine translates message expression
/// into a call to objc_msgSend_stret() entry point. Tricky part is that
/// nil check on receiver must be performed before calling objc_msgSend_stret.
/// MsgSendStretFlavor - function declaration objc_msgSend_stret(...)
/// msgSendType - function type of objc_msgSend_stret(...)
/// returnType - Result type of the method being synthesized.
/// ArgTypes - type of the arguments passed to objc_msgSend_stret, starting with receiver type.
/// MsgExprs - list of argument expressions being passed to objc_msgSend_stret, 
/// starting with receiver.
/// Method - Method being rewritten.
Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
                                                 QualType msgSendType, 
                                                 QualType returnType, 
                                                 SmallVectorImpl<QualType> &ArgTypes,
                                                 SmallVectorImpl<Expr*> &MsgExprs,
                                                 ObjCMethodDecl *Method) {
  // Now do the "normal" pointer to function cast.
  QualType castType = getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
                                            Method ? Method->isVariadic() : false);
  castType = Context->getPointerType(castType);
  
  // build type for containing the objc_msgSend_stret object.
  static unsigned stretCount=0;
  std::string name = "__Stret"; name += utostr(stretCount);
  std::string str = 
    "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
  str += "struct "; str += name;
  str += " {\n\t";
  str += name;
  str += "(id receiver, SEL sel";
  for (unsigned i = 2; i < ArgTypes.size(); i++) {
    std::string ArgName = "arg"; ArgName += utostr(i);
    ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy());
    str += ", "; str += ArgName;
  }
  // could be vararg.
  for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
    std::string ArgName = "arg"; ArgName += utostr(i);
    MsgExprs[i]->getType().getAsStringInternal(ArgName,
                                               Context->getPrintingPolicy());
    str += ", "; str += ArgName;
  }
  
  str += ") {\n";
  str += "\t  if (receiver == 0)\n";
  str += "\t    memset((void*)&s, 0, sizeof(s));\n";
  str += "\t  else\n";
  str += "\t    s = (("; str += castType.getAsString(Context->getPrintingPolicy());
  str += ")(void *)objc_msgSend_stret)(receiver, sel";
  for (unsigned i = 2; i < ArgTypes.size(); i++) {
    str += ", arg"; str += utostr(i);
  }
  // could be vararg.
  for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
    str += ", arg"; str += utostr(i);
  }
  
  str += ");\n";
  str += "\t}\n";
  str += "\t"; str += returnType.getAsString(Context->getPrintingPolicy());
  str += " s;\n";
  str += "};\n\n";
  SourceLocation FunLocStart;
  if (CurFunctionDef)
    FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
  else {
    assert(CurMethodDef && "SynthMsgSendStretCallExpr - CurMethodDef is null");
    FunLocStart = CurMethodDef->getLocStart();
  }

  InsertText(FunLocStart, str);
  ++stretCount;
  
  // AST for __Stretn(receiver, args).s;
  IdentifierInfo *ID = &Context->Idents.get(name);
  FunctionDecl *FD = FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
                                          SourceLocation(), ID, castType, 0, SC_Extern,
                                          SC_None, false, false);
  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, castType, VK_RValue,
                                               SourceLocation());
  CallExpr *STCE = new (Context) CallExpr(*Context, DRE, MsgExprs,
                                          castType, VK_LValue, SourceLocation());
  
  FieldDecl *FieldD = FieldDecl::Create(*Context, 0, SourceLocation(),
                                    SourceLocation(),
                                    &Context->Idents.get("s"),
                                    returnType, 0,
                                    /*BitWidth=*/0, /*Mutable=*/true,
                                    ICIS_NoInit);
  MemberExpr *ME = new (Context) MemberExpr(STCE, false, FieldD, SourceLocation(),
                                            FieldD->getType(), VK_LValue,
                                            OK_Ordinary);

  return ME;
}

Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
                                    SourceLocation StartLoc,
                                    SourceLocation EndLoc) {
  if (!SelGetUidFunctionDecl)
    SynthSelGetUidFunctionDecl();
  if (!MsgSendFunctionDecl)
    SynthMsgSendFunctionDecl();
  if (!MsgSendSuperFunctionDecl)
    SynthMsgSendSuperFunctionDecl();
  if (!MsgSendStretFunctionDecl)
    SynthMsgSendStretFunctionDecl();
  if (!MsgSendSuperStretFunctionDecl)
    SynthMsgSendSuperStretFunctionDecl();
  if (!MsgSendFpretFunctionDecl)
    SynthMsgSendFpretFunctionDecl();
  if (!GetClassFunctionDecl)
    SynthGetClassFunctionDecl();
  if (!GetSuperClassFunctionDecl)
    SynthGetSuperClassFunctionDecl();
  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->isRecordType())
      MsgSendStretFlavor = MsgSendStretFunctionDecl;
    else if (resultType->isRealFloatingType())
      MsgSendFlavor = MsgSendFpretFunctionDecl;
  }

  // Synthesize a call to objc_msgSend().
  SmallVector<Expr*, 8> MsgExprs;
  switch (Exp->getReceiverKind()) {
  case ObjCMessageExpr::SuperClass: {
    MsgSendFlavor = MsgSendSuperFunctionDecl;
    if (MsgSendStretFlavor)
      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");

    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();

    SmallVector<Expr*, 4> InitExprs;

    // set the receiver to self, the first argument to all methods.
    InitExprs.push_back(
      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
                               CK_BitCast,
                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
                                             false,
                                             Context->getObjCIdType(),
                                             VK_RValue,
                                             SourceLocation()))
                        ); // set the 'receiver'.

    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
    SmallVector<Expr*, 8> ClsExprs;
    QualType argType = Context->getPointerType(Context->CharTy);
    ClsExprs.push_back(StringLiteral::Create(*Context,
                                   ClassDecl->getIdentifier()->getName(),
                                   StringLiteral::Ascii, false,
                                   argType, SourceLocation()));
    // (Class)objc_getClass("CurrentClass")
    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
                                                 &ClsExprs[0],
                                                 ClsExprs.size(),
                                                 StartLoc,
                                                 EndLoc);
    ClsExprs.clear();
    ClsExprs.push_back(Cls);
    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
                                       &ClsExprs[0], ClsExprs.size(),
                                       StartLoc, EndLoc);
    
    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
    // To turn off a warning, type-cast to 'id'
    InitExprs.push_back( // set 'super class', using class_getSuperclass().
                        NoTypeInfoCStyleCastExpr(Context,
                                                 Context->getObjCIdType(),
                                                 CK_BitCast, Cls));
    // struct __rw_objc_super
    QualType superType = getSuperStructType();
    Expr *SuperRep;

    if (LangOpts.MicrosoftExt) {
      SynthSuperContructorFunctionDecl();
      // Simulate a contructor call...
      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
                                                   false, superType, VK_LValue,
                                                   SourceLocation());
      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
                                        superType, VK_LValue,
                                        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 __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
      //
      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
                               Context->getPointerType(SuperRep->getType()),
                                             VK_RValue, OK_Ordinary,
                                             SourceLocation());
      SuperRep = NoTypeInfoCStyleCastExpr(Context,
                                          Context->getPointerType(superType),
                                          CK_BitCast, SuperRep);
    } else {
      // (struct __rw_objc_super) { <exprs from above> }
      InitListExpr *ILE =
        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
                                   SourceLocation());
      TypeSourceInfo *superTInfo
        = Context->getTrivialTypeSourceInfo(superType);
      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
                                                   superType, VK_LValue,
                                                   ILE, false);
      // struct __rw_objc_super *
      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
                               Context->getPointerType(SuperRep->getType()),
                                             VK_RValue, OK_Ordinary,
                                             SourceLocation());
    }
    MsgExprs.push_back(SuperRep);
    break;
  }

  case ObjCMessageExpr::Class: {
    SmallVector<Expr*, 8> ClsExprs;
    QualType argType = Context->getPointerType(Context->CharTy);
    ObjCInterfaceDecl *Class
      = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
    IdentifierInfo *clsName = Class->getIdentifier();
    ClsExprs.push_back(StringLiteral::Create(*Context,
                                             clsName->getName(),
                                             StringLiteral::Ascii, false,
                                             argType, SourceLocation()));
    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
                                                 &ClsExprs[0],
                                                 ClsExprs.size(), 
                                                 StartLoc, EndLoc);
    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
                                                 Context->getObjCIdType(),
                                                 CK_BitCast, Cls);
    MsgExprs.push_back(ArgExpr);
    break;
  }

  case ObjCMessageExpr::SuperInstance:{
    MsgSendFlavor = MsgSendSuperFunctionDecl;
    if (MsgSendStretFlavor)
      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
    SmallVector<Expr*, 4> InitExprs;

    InitExprs.push_back(
      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
                               CK_BitCast,
                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
                                             false,
                                             Context->getObjCIdType(),
                                             VK_RValue, SourceLocation()))
                        ); // set the 'receiver'.
    
    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
    SmallVector<Expr*, 8> ClsExprs;
    QualType argType = Context->getPointerType(Context->CharTy);
    ClsExprs.push_back(StringLiteral::Create(*Context,
                                   ClassDecl->getIdentifier()->getName(),
                                   StringLiteral::Ascii, false, argType,
                                   SourceLocation()));
    // (Class)objc_getClass("CurrentClass")
    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
                                                 &ClsExprs[0],
                                                 ClsExprs.size(), 
                                                 StartLoc, EndLoc);
    ClsExprs.clear();
    ClsExprs.push_back(Cls);
    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
                                       &ClsExprs[0], ClsExprs.size(),
                                       StartLoc, EndLoc);
    
    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
    // To turn off a warning, type-cast to 'id'
    InitExprs.push_back(
      // set 'super class', using class_getSuperclass().
      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
                               CK_BitCast, Cls));
    // struct __rw_objc_super
    QualType superType = getSuperStructType();
    Expr *SuperRep;

    if (LangOpts.MicrosoftExt) {
      SynthSuperContructorFunctionDecl();
      // Simulate a contructor call...
      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
                                                   false, superType, VK_LValue,
                                                   SourceLocation());
      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
                                        superType, VK_LValue, 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 __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
      //
      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
                               Context->getPointerType(SuperRep->getType()),
                               VK_RValue, OK_Ordinary,
                               SourceLocation());
      SuperRep = NoTypeInfoCStyleCastExpr(Context,
                               Context->getPointerType(superType),
                               CK_BitCast, SuperRep);
    } else {
      // (struct __rw_objc_super) { <exprs from above> }
      InitListExpr *ILE =
        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
                                   SourceLocation());
      TypeSourceInfo *superTInfo
        = Context->getTrivialTypeSourceInfo(superType);
      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
                                                   superType, VK_RValue, ILE,
                                                   false);
    }
    MsgExprs.push_back(SuperRep);
    break;
  }

  case ObjCMessageExpr::Instance: {
    // Remove all type-casts because it may contain objc-style types; e.g.
    // Foo<Proto> *.
    Expr *recExpr = Exp->getInstanceReceiver();
    while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
      recExpr = CE->getSubExpr();
    CastKind CK = recExpr->getType()->isObjCObjectPointerType()
                    ? CK_BitCast : recExpr->getType()->isBlockPointerType()
                                     ? CK_BlockPointerToObjCPointerCast
                                     : CK_CPointerToObjCPointerCast;

    recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
                                       CK, recExpr);
    MsgExprs.push_back(recExpr);
    break;
  }
  }

  // Create a call to sel_registerName("selName"), it will be the 2nd argument.
  SmallVector<Expr*, 8> SelExprs;
  QualType argType = Context->getPointerType(Context->CharTy);
  SelExprs.push_back(StringLiteral::Create(*Context,
                                       Exp->getSelector().getAsString(),
                                       StringLiteral::Ascii, false,
                                       argType, SourceLocation()));
  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
                                                 &SelExprs[0], SelExprs.size(),
                                                  StartLoc,
                                                  EndLoc);
  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();
      if (needToScanForQualifiers(type))
        type = Context->getObjCIdType();
      // Make sure we convert "type (^)(...)" to "type (*)(...)".
      (void)convertBlockPointerToFunctionPointer(type);
      const Expr *SubExpr = ICE->IgnoreParenImpCasts();
      CastKind CK;
      if (SubExpr->getType()->isIntegralType(*Context) && 
          type->isBooleanType()) {
        CK = CK_IntegralToBoolean;
      } else if (type->isObjCObjectPointerType()) {
        if (SubExpr->getType()->isBlockPointerType()) {
          CK = CK_BlockPointerToObjCPointerCast;
        } else if (SubExpr->getType()->isPointerType()) {
          CK = CK_CPointerToObjCPointerCast;
        } else {
          CK = CK_BitCast;
        }
      } else {
        CK = CK_BitCast;
      }

      userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
    }
    // 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();
        CastKind CK;
        if (userExpr->getType()->isIntegralType(*Context)) {
          CK = CK_IntegralToPointer;
        } else if (userExpr->getType()->isBlockPointerType()) {
          CK = CK_BlockPointerToObjCPointerCast;
        } else if (userExpr->getType()->isPointerType()) {
          CK = CK_CPointerToObjCPointerCast;
        } else {
          CK = CK_BitCast;
        }
        userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
                                            CK, userExpr);
      }
    }
    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 RewritePropertyOrImplicitSetter() usage for more info.
    //Exp->setArg(i, 0);
  }
  // Generate the funky cast.
  CastExpr *cast;
  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 (*)(...)".
      (void)convertBlockPointerToFunctionPointer(t);
      ArgTypes.push_back(t);
    }
    returnType = Exp->getType();
    convertToUnqualifiedObjCType(returnType);
    (void)convertBlockPointerToFunctionPointer(returnType);
  } 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, false, msgSendType,
                                               VK_LValue, 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 = NoTypeInfoCStyleCastExpr(Context,
                                  Context->getPointerType(Context->VoidTy),
                                  CK_BitCast, DRE);

  // Now do the "normal" pointer to function cast.
  QualType castType =
    getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
      // If we don't have a method decl, force a variadic cast.
      Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true);
  castType = Context->getPointerType(castType);
  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
                                  cast);

  // Don't forget the parens to enforce the proper binding.
  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);

  const FunctionType *FT = msgSendType->getAs<FunctionType>();
  CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs,
                                        FT->getResultType(), VK_RValue, EndLoc);
  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.

    Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor, 
                                           msgSendType, returnType, 
                                           ArgTypes, MsgExprs,
                                           Exp->getMethodDecl());

    // Build sizeof(returnType)
    UnaryExprOrTypeTraitExpr *sizeofExpr =
       new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf,
                                 Context->getTrivialTypeSourceInfo(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 = IntegerLiteral::Create(*Context,
                                                   llvm::APInt(IntSize, 8),
                                                   Context->IntTy,
                                                   SourceLocation());
    BinaryOperator *lessThanExpr = 
      new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy,
                                   VK_RValue, OK_Ordinary, SourceLocation(),
                                   false);
    // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
    ConditionalOperator *CondExpr =
      new (Context) ConditionalOperator(lessThanExpr,
                                        SourceLocation(), CE,
                                        SourceLocation(), STCE,
                                        returnType, VK_RValue, OK_Ordinary);
    ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
                                            CondExpr);
  }
  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
  return ReplacingStmt;
}

Stmt *RewriteModernObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
  Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(),
                                         Exp->getLocEnd());

  // Now do the actual rewrite.
  ReplaceStmt(Exp, ReplacingStmt);

  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
  return ReplacingStmt;
}

// typedef struct objc_object Protocol;
QualType RewriteModernObjC::getProtocolType() {
  if (!ProtocolTypeDecl) {
    TypeSourceInfo *TInfo
      = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
    ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
                                           SourceLocation(), SourceLocation(),
                                           &Context->Idents.get("Protocol"),
                                           TInfo);
  }
  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
/// RewriteModernObjC::HandleTranslationUnit().
Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
  std::string Name = "_OBJC_PROTOCOL_REFERENCE_$_" + 
                      Exp->getProtocol()->getNameAsString();
  IdentifierInfo *ID = &Context->Idents.get(Name);
  VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
                                SourceLocation(), ID, getProtocolType(), 0,
                                SC_Extern, SC_None);
  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
                                               VK_LValue, SourceLocation());
  Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
                             Context->getPointerType(DRE->getType()),
                             VK_RValue, OK_Ordinary, SourceLocation());
  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(),
                                                CK_BitCast,
                                                DerefExpr);
  ReplaceStmt(Exp, castExpr);
  ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl());
  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
  return castExpr;

}

bool RewriteModernObjC::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;
}

/// IsTagDefinedInsideClass - This routine checks that a named tagged type 
/// is defined inside an objective-c class. If so, it returns true. 
bool RewriteModernObjC::IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, 
                                                TagDecl *Tag,
                                                bool &IsNamedDefinition) {
  if (!IDecl)
    return false;
  SourceLocation TagLocation;
  if (RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
    RD = RD->getDefinition();
    if (!RD || !RD->getDeclName().getAsIdentifierInfo())
      return false;
    IsNamedDefinition = true;
    TagLocation = RD->getLocation();
    return Context->getSourceManager().isBeforeInTranslationUnit(
                                          IDecl->getLocation(), TagLocation);
  }
  if (EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
    if (!ED || !ED->getDeclName().getAsIdentifierInfo())
      return false;
    IsNamedDefinition = true;
    TagLocation = ED->getLocation();
    return Context->getSourceManager().isBeforeInTranslationUnit(
                                          IDecl->getLocation(), TagLocation);

  }
  return false;
}

/// RewriteObjCFieldDeclType - This routine rewrites a type into the buffer.
/// It handles elaborated types, as well as enum types in the process.
bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, 
                                                 std::string &Result) {
  if (isa<TypedefType>(Type)) {
    Result += "\t";
    return false;
  }
    
  if (Type->isArrayType()) {
    QualType ElemTy = Context->getBaseElementType(Type);
    return RewriteObjCFieldDeclType(ElemTy, Result);
  }
  else if (Type->isRecordType()) {
    RecordDecl *RD = Type->getAs<RecordType>()->getDecl();
    if (RD->isCompleteDefinition()) {
      if (RD->isStruct())
        Result += "\n\tstruct ";
      else if (RD->isUnion())
        Result += "\n\tunion ";
      else
        assert(false && "class not allowed as an ivar type");
      
      Result += RD->getName();
      if (GlobalDefinedTags.count(RD)) {
        // struct/union is defined globally, use it.
        Result += " ";
        return true;
      }
      Result += " {\n";
      for (RecordDecl::field_iterator i = RD->field_begin(), 
           e = RD->field_end(); i != e; ++i) {
        FieldDecl *FD = *i;
        RewriteObjCFieldDecl(FD, Result);
      }
      Result += "\t} "; 
      return true;
    }
  }
  else if (Type->isEnumeralType()) {
    EnumDecl *ED = Type->getAs<EnumType>()->getDecl();
    if (ED->isCompleteDefinition()) {
      Result += "\n\tenum ";
      Result += ED->getName();
      if (GlobalDefinedTags.count(ED)) {
        // Enum is globall defined, use it.
        Result += " ";
        return true;
      }
      
      Result += " {\n";
      for (EnumDecl::enumerator_iterator EC = ED->enumerator_begin(),
           ECEnd = ED->enumerator_end(); EC != ECEnd; ++EC) {
        Result += "\t"; Result += EC->getName(); Result += " = ";
        llvm::APSInt Val = EC->getInitVal();
        Result += Val.toString(10);
        Result += ",\n";
      }
      Result += "\t} "; 
      return true;
    }
  }
  
  Result += "\t";
  convertObjCTypeToCStyleType(Type);
  return false;
}


/// RewriteObjCFieldDecl - This routine rewrites a field into the buffer.
/// It handles elaborated types, as well as enum types in the process.
void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl, 
                                             std::string &Result) {
  QualType Type = fieldDecl->getType();
  std::string Name = fieldDecl->getNameAsString();
  
  bool EleboratedType = RewriteObjCFieldDeclType(Type, Result); 
  if (!EleboratedType)
    Type.getAsStringInternal(Name, Context->getPrintingPolicy());
  Result += Name;
  if (fieldDecl->isBitField()) {
    Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context));
  }
  else if (EleboratedType && Type->isArrayType()) {
    CanQualType CType = Context->getCanonicalType(Type);
    while (isa<ArrayType>(CType)) {
      if (const ConstantArrayType *CAT = Context->getAsConstantArrayType(CType)) {
        Result += "[";
        llvm::APInt Dim = CAT->getSize();
        Result += utostr(Dim.getZExtValue());
        Result += "]";
      }
      CType = CType->getAs<ArrayType>()->getElementType();
    }
  }
  
  Result += ";\n";
}

/// RewriteLocallyDefinedNamedAggregates - This routine rewrites locally defined
/// named aggregate types into the input buffer.
void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 
                                             std::string &Result) {
  QualType Type = fieldDecl->getType();
  if (isa<TypedefType>(Type))
    return;
  if (Type->isArrayType())
    Type = Context->getBaseElementType(Type);
  ObjCContainerDecl *IDecl = 
    dyn_cast<ObjCContainerDecl>(fieldDecl->getDeclContext());
  
  TagDecl *TD = 0;
  if (Type->isRecordType()) {
    TD = Type->getAs<RecordType>()->getDecl();
  }
  else if (Type->isEnumeralType()) {
    TD = Type->getAs<EnumType>()->getDecl();
  }
  
  if (TD) {
    if (GlobalDefinedTags.count(TD))
      return;
    
    bool IsNamedDefinition = false;
    if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
      RewriteObjCFieldDeclType(Type, Result);
      Result += ";";
    }
    if (IsNamedDefinition)
      GlobalDefinedTags.insert(TD);
  }
    
}

/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to
/// an objective-c class with ivars.
void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
                                               std::string &Result) {
  assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
  assert(CDecl->getName() != "" &&
         "Name missing in SynthesizeObjCInternalStruct");
  ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
  SmallVector<ObjCIvarDecl *, 8> IVars;
  for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
       IVD; IVD = IVD->getNextIvar())
    IVars.push_back(IVD);
  
  SourceLocation LocStart = CDecl->getLocStart();
  SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc();
  
  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->isThisDeclarationADefinition() || IVars.size() == 0) &&
      (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
    ReplaceText(LocStart, endBuf-startBuf, Result);
    return;
  }
  
  // Insert named struct/union definitions inside class to
  // outer scope. This follows semantics of locally defined
  // struct/unions in objective-c classes.
  for (unsigned i = 0, e = IVars.size(); i < e; i++)
    RewriteLocallyDefinedNamedAggregates(IVars[i], Result);

  Result += "\nstruct ";
  Result += CDecl->getNameAsString();
  Result += "_IMPL {\n";
  
  if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
    Result += "\tstruct "; Result += RCDecl->getNameAsString();
    Result += "_IMPL "; Result += RCDecl->getNameAsString();
    Result += "_IVARS;\n";
  }
  
  for (unsigned i = 0, e = IVars.size(); i < e; i++)
    RewriteObjCFieldDecl(IVars[i], Result);

  Result += "};\n";
  endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
  ReplaceText(LocStart, endBuf-startBuf, Result);
  // Mark this struct as having been generated.
  if (!ObjCSynthesizedStructs.insert(CDecl))
    llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct");
}

/// RewriteIvarOffsetSymbols - Rewrite ivar offset symbols of those ivars which
/// have been referenced in an ivar access expression.
void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
                                                  std::string &Result) {
  // write out ivar offset symbols which have been referenced in an ivar
  // access expression.
  llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];
  if (Ivars.empty())
    return;
  for (llvm::SmallPtrSet<ObjCIvarDecl *, 8>::iterator i = Ivars.begin(),
       e = Ivars.end(); i != e; i++) {
    ObjCIvarDecl *IvarDecl = (*i);
    Result += "\n";
    if (LangOpts.MicrosoftExt)
      Result += "__declspec(allocate(\".objc_ivar$B\")) ";
    Result += "extern \"C\" ";
    if (LangOpts.MicrosoftExt && 
        IvarDecl->getAccessControl() != ObjCIvarDecl::Private &&
        IvarDecl->getAccessControl() != ObjCIvarDecl::Package)
        Result += "__declspec(dllimport) ";

    Result += "unsigned long ";
    WriteInternalIvarName(CDecl, IvarDecl, Result);
    Result += ";";
  }
}

//===----------------------------------------------------------------------===//
// Meta Data Emission
//===----------------------------------------------------------------------===//


/// RewriteImplementations - This routine rewrites all method implementations
/// and emits meta-data.

void RewriteModernObjC::RewriteImplementations() {
  int ClsDefCount = ClassImplementation.size();
  int CatDefCount = CategoryImplementation.size();

  // Rewrite implemented methods
  for (int i = 0; i < ClsDefCount; i++) {
    ObjCImplementationDecl *OIMP = ClassImplementation[i];
    ObjCInterfaceDecl *CDecl = OIMP->getClassInterface();
    if (CDecl->isImplicitInterfaceDecl())
      assert(false &&
             "Legacy implicit interface rewriting not supported in moder abi");
    RewriteImplementationDecl(OIMP);
  }

  for (int i = 0; i < CatDefCount; i++) {
    ObjCCategoryImplDecl *CIMP = CategoryImplementation[i];
    ObjCInterfaceDecl *CDecl = CIMP->getClassInterface();
    if (CDecl->isImplicitInterfaceDecl())
      assert(false &&
             "Legacy implicit interface rewriting not supported in moder abi");
    RewriteImplementationDecl(CIMP);
  }
}

void RewriteModernObjC::RewriteByRefString(std::string &ResultStr, 
                                     const std::string &Name,
                                     ValueDecl *VD, bool def) {
  assert(BlockByRefDeclNo.count(VD) && 
         "RewriteByRefString: ByRef decl missing");
  if (def)
    ResultStr += "struct ";
  ResultStr += "__Block_byref_" + Name + 
    "_" + utostr(BlockByRefDeclNo[VD]) ;
}

static bool HasLocalVariableExternalStorage(ValueDecl *VD) {
  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
    return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
  return false;
}

std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
                                                   StringRef funcName,
                                                   std::string Tag) {
  const FunctionType *AFT = CE->getFunctionType();
  QualType RT = AFT->getResultType();
  std::string StructRef = "struct " + Tag;
  SourceLocation BlockLoc = CE->getExprLoc();
  std::string S;
  ConvertSourceLocationToLineDirective(BlockLoc, S);
  
  S += "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" +
         funcName.str() + "_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();
      QualType QT = (*AI)->getType();
      (void)convertBlockPointerToFunctionPointer(QT);
      QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy());
      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 (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
       E = BlockByRefDecls.end(); I != E; ++I) {
    S += "  ";
    std::string Name = (*I)->getNameAsString();
    std::string TypeString;
    RewriteByRefString(TypeString, Name, (*I));
    TypeString += " *";
    Name = TypeString + Name;
    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
  }
  // Next, emit a declaration for all "by copy" declarations.
  for (SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
       E = BlockByCopyDecls.end(); I != E; ++I) {
    S += "  ";
    // 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())) {
      RewriteBlockPointerTypeVariable(S, (*I));
      S += " = (";
      RewriteBlockPointerType(S, (*I)->getType());
      S += ")";
      S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
    }
    else {
      std::string Name = (*I)->getNameAsString();
      QualType QT = (*I)->getType();
      if (HasLocalVariableExternalStorage(*I))
        QT = Context->getPointerType(QT);
      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
      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 RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
                                                   StringRef 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) {
    ValueDecl *VD = (*I);
    S += "_Block_object_assign((void*)&dst->";
    S += (*I)->getNameAsString();
    S += ", (void*)src->";
    S += (*I)->getNameAsString();
    if (BlockByRefDeclsPtrSet.count((*I)))
      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
    else if (VD->getType()->isBlockPointerType())
      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
    else
      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
  }
  S += "}\n";
  
  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) {
    ValueDecl *VD = (*I);
    S += "_Block_object_dispose((void*)src->";
    S += (*I)->getNameAsString();
    if (BlockByRefDeclsPtrSet.count((*I)))
      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
    else if (VD->getType()->isBlockPointerType())
      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
    else
      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
  }
  S += "}\n";
  return S;
}

std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
                                             std::string Desc) {
  std::string S = "\nstruct " + Tag;
  std::string Constructor = "  " + Tag;

  S += " {\n  struct __block_impl impl;\n";
  S += "  struct " + Desc;
  S += "* Desc;\n";

  Constructor += "(void *fp, "; // Invoke function pointer.
  Constructor += "struct " + Desc; // Descriptor pointer.
  Constructor += " *desc";

  if (BlockDeclRefs.size()) {
    // Output all "by copy" declarations.
    for (SmallVector<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 {
        QualType QT = (*I)->getType();
        if (HasLocalVariableExternalStorage(*I))
          QT = Context->getPointerType(QT);
        QT.getAsStringInternal(FieldName, Context->getPrintingPolicy());
        QT.getAsStringInternal(ArgName, Context->getPrintingPolicy());
        Constructor += ", " + ArgName;
      }
      S += FieldName + ";\n";
    }
    // Output all "by ref" declarations.
    for (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
         E = BlockByRefDecls.end(); I != E; ++I) {
      S += "  ";
      std::string FieldName = (*I)->getNameAsString();
      std::string ArgName = "_" + FieldName;
      {
        std::string TypeString;
        RewriteByRefString(TypeString, FieldName, (*I));
        TypeString += " *";
        FieldName = TypeString + FieldName;
        ArgName = TypeString + ArgName;
        Constructor += ", " + ArgName;
      }
      S += FieldName + "; // by ref\n";
    }
    // Finish writing the constructor.
    Constructor += ", int flags=0)";
    // Initialize all "by copy" arguments.
    bool firsTime = true;
    for (SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
         E = BlockByCopyDecls.end(); I != E; ++I) {
      std::string Name = (*I)->getNameAsString();
        if (firsTime) {
          Constructor += " : ";
          firsTime = false;
        }
        else
          Constructor += ", ";
        if (isTopLevelBlockPointerType((*I)->getType()))
          Constructor += Name + "((struct __block_impl *)_" + Name + ")";
        else
          Constructor += Name + "(_" + Name + ")";
    }
    // Initialize all "by ref" arguments.
    for (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
         E = BlockByRefDecls.end(); I != E; ++I) {
      std::string Name = (*I)->getNameAsString();
      if (firsTime) {
        Constructor += " : ";
        firsTime = false;
      }
      else
        Constructor += ", ";
      Constructor += Name + "(_" + Name + "->__forwarding)";
    }
    
    Constructor += " {\n";
    if (GlobalVarDecl)
      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
    else
      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";

    Constructor += "    Desc = desc;\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.Flags = flags;\n    impl.FuncPtr = fp;\n";
    Constructor += "    Desc = desc;\n";
  }
  Constructor += "  ";
  Constructor += "}\n";
  S += Constructor;
  S += "};\n";
  return S;
}

std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag, 
                                                   std::string ImplTag, int i,
                                                   StringRef FunName,
                                                   unsigned hasCopy) {
  std::string S = "\nstatic struct " + DescTag;
  
  S += " {\n  size_t reserved;\n";
  S += "  size_t Block_size;\n";
  if (hasCopy) {
    S += "  void (*copy)(struct ";
    S += ImplTag; S += "*, struct ";
    S += ImplTag; S += "*);\n";
    
    S += "  void (*dispose)(struct ";
    S += ImplTag; S += "*);\n";
  }
  S += "} ";

  S += DescTag + "_DATA = { 0, sizeof(struct ";
  S += ImplTag + ")";
  if (hasCopy) {
    S += ", __" + FunName.str() + "_block_copy_" + utostr(i);
    S += ", __" + FunName.str() + "_block_dispose_" + utostr(i);
  }
  S += "};\n";
  return S;
}

void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
                                          StringRef FunName) {
  bool RewriteSC = (GlobalVarDecl &&
                    !Blocks.empty() &&
                    GlobalVarDecl->getStorageClass() == SC_Static &&
                    GlobalVarDecl->getType().getCVRQualifiers());
  if (RewriteSC) {
    std::string SC(" void __");
    SC += GlobalVarDecl->getNameAsString();
    SC += "() {}";
    InsertText(FunLocStart, SC);
  }
  
  // Insert closures that were part of the function.
  for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
    CollectBlockDeclRefInfo(Blocks[i]);
    // Need to copy-in the inner copied-in variables not actually used in this
    // block.
    for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
      DeclRefExpr *Exp = InnerDeclRefs[count++];
      ValueDecl *VD = Exp->getDecl();
      BlockDeclRefs.push_back(Exp);
      if (!VD->hasAttr<BlocksAttr>()) {
        if (!BlockByCopyDeclsPtrSet.count(VD)) {
          BlockByCopyDeclsPtrSet.insert(VD);
          BlockByCopyDecls.push_back(VD);
        }
        continue;
      }

      if (!BlockByRefDeclsPtrSet.count(VD)) {
        BlockByRefDeclsPtrSet.insert(VD);
        BlockByRefDecls.push_back(VD);
      }

      // imported objects in the inner blocks not used in the outer
      // blocks must be copied/disposed in the outer block as well.
      if (VD->getType()->isObjCObjectPointerType() || 
          VD->getType()->isBlockPointerType())
        ImportedBlockDecls.insert(VD);
    }

    std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i);
    std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i);

    std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);

    InsertText(FunLocStart, CI);

    std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);

    InsertText(FunLocStart, CF);

    if (ImportedBlockDecls.size()) {
      std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
      InsertText(FunLocStart, HF);
    }
    std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
                                               ImportedBlockDecls.size() > 0);
    InsertText(FunLocStart, BD);

    BlockDeclRefs.clear();
    BlockByRefDecls.clear();
    BlockByRefDeclsPtrSet.clear();
    BlockByCopyDecls.clear();
    BlockByCopyDeclsPtrSet.clear();
    ImportedBlockDecls.clear();
  }
  if (RewriteSC) {
    // Must insert any 'const/volatile/static here. Since it has been
    // removed as result of rewriting of block literals.
    std::string SC;
    if (GlobalVarDecl->getStorageClass() == SC_Static)
      SC = "static ";
    if (GlobalVarDecl->getType().isConstQualified())
      SC += "const ";
    if (GlobalVarDecl->getType().isVolatileQualified())
      SC += "volatile ";
    if (GlobalVarDecl->getType().isRestrictQualified())
      SC += "restrict ";
    InsertText(FunLocStart, SC);
  }
  if (GlobalConstructionExp) {
    // extra fancy dance for global literal expression.
    
    // Always the latest block expression on the block stack.
    std::string Tag = "__";
    Tag += FunName;
    Tag += "_block_impl_";
    Tag += utostr(Blocks.size()-1);
    std::string globalBuf = "static ";
    globalBuf += Tag; globalBuf += " ";
    std::string SStr;
  
    llvm::raw_string_ostream constructorExprBuf(SStr);
    GlobalConstructionExp->printPretty(constructorExprBuf, 0,
                                         PrintingPolicy(LangOpts));
    globalBuf += constructorExprBuf.str();
    globalBuf += ";\n";
    InsertText(FunLocStart, globalBuf);
    GlobalConstructionExp = 0;
  }

  Blocks.clear();
  InnerDeclRefsCount.clear();
  InnerDeclRefs.clear();
  RewrittenBlockExprs.clear();
}

void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
  SourceLocation FunLocStart = 
    (!Blocks.empty()) ? getFunctionSourceLocation(*this, FD)
                      : FD->getTypeSpecStartLoc();
  StringRef FuncName = FD->getName();

  SynthesizeBlockLiterals(FunLocStart, FuncName);
}

static void BuildUniqueMethodName(std::string &Name,
                                  ObjCMethodDecl *MD) {
  ObjCInterfaceDecl *IFace = MD->getClassInterface();
  Name = IFace->getName();
  Name += "__" + MD->getSelector().getAsString();
  // Convert colons to underscores.
  std::string::size_type loc = 0;
  while ((loc = Name.find(":", loc)) != std::string::npos)
    Name.replace(loc, 1, "_");
}

void RewriteModernObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
  //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
  //SourceLocation FunLocStart = MD->getLocStart();
  SourceLocation FunLocStart = MD->getLocStart();
  std::string FuncName;
  BuildUniqueMethodName(FuncName, MD);
  SynthesizeBlockLiterals(FunLocStart, FuncName);
}

void RewriteModernObjC::GetBlockDeclRefExprs(Stmt *S) {
  for (Stmt::child_range CI = S->children(); CI; ++CI)
    if (*CI) {
      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
        GetBlockDeclRefExprs(CBE->getBody());
      else
        GetBlockDeclRefExprs(*CI);
    }
  // Handle specific things.
  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
    if (DRE->refersToEnclosingLocal()) {
      // FIXME: Handle enums.
      if (!isa<FunctionDecl>(DRE->getDecl()))
        BlockDeclRefs.push_back(DRE);
      if (HasLocalVariableExternalStorage(DRE->getDecl()))
        BlockDeclRefs.push_back(DRE);
    }
  }
  
  return;
}

void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S, 
                SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs,
                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
  for (Stmt::child_range CI = S->children(); CI; ++CI)
    if (*CI) {
      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
        InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
        GetInnerBlockDeclRefExprs(CBE->getBody(),
                                  InnerBlockDeclRefs,
                                  InnerContexts);
      }
      else
        GetInnerBlockDeclRefExprs(*CI,
                                  InnerBlockDeclRefs,
                                  InnerContexts);

    }
  // Handle specific things.
  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
    if (DRE->refersToEnclosingLocal()) {
      if (!isa<FunctionDecl>(DRE->getDecl()) &&
          !InnerContexts.count(DRE->getDecl()->getDeclContext()))
        InnerBlockDeclRefs.push_back(DRE);
      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
        if (Var->isFunctionOrMethodVarDecl())
          ImportedLocalExternalDecls.insert(Var);
    }
  }
  
  return;
}

/// convertObjCTypeToCStyleType - This routine converts such objc types
/// as qualified objects, and blocks to their closest c/c++ types that
/// it can. It returns true if input type was modified.
bool RewriteModernObjC::convertObjCTypeToCStyleType(QualType &T) {
  QualType oldT = T;
  convertBlockPointerToFunctionPointer(T);
  if (T->isFunctionPointerType()) {
    QualType PointeeTy;
    if (const PointerType* PT = T->getAs<PointerType>()) {
      PointeeTy = PT->getPointeeType();
      if (const FunctionType *FT = PointeeTy->getAs<FunctionType>()) {
        T = convertFunctionTypeOfBlocks(FT);
        T = Context->getPointerType(T);
      }
    }
  }
  
  convertToUnqualifiedObjCType(T);
  return T != oldT;
}

/// convertFunctionTypeOfBlocks - This routine converts a function type
/// whose result type may be a block pointer or whose argument type(s)
/// might be block pointers to an equivalent function type replacing
/// all block pointers to function pointers.
QualType RewriteModernObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {
  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
  // FTP will be null for closures that don't take arguments.
  // Generate a funky cast.
  SmallVector<QualType, 8> ArgTypes;
  QualType Res = FT->getResultType();
  bool modified = convertObjCTypeToCStyleType(Res);
  
  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 (convertObjCTypeToCStyleType(t))
        modified = true;
      ArgTypes.push_back(t);
    }
  }
  QualType FuncType;
  if (modified)
    FuncType = getSimpleFunctionType(Res, &ArgTypes[0], ArgTypes.size());
  else FuncType = QualType(FT, 0);
  return FuncType;
}

Stmt *RewriteModernObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
  // Navigate to relevant type information.
  const BlockPointerType *CPT = 0;

  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
    CPT = DRE->getType()->getAs<BlockPointerType>();
  } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
    CPT = MExpr->getType()->getAs<BlockPointerType>();
  } 
  else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
    return SynthesizeBlockCall(Exp, PRE->getSubExpr());
  }
  else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 
    CPT = IEXPR->getType()->getAs<BlockPointerType>();
  else if (const ConditionalOperator *CEXPR = 
            dyn_cast<ConditionalOperator>(BlockExp)) {
    Expr *LHSExp = CEXPR->getLHS();
    Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
    Expr *RHSExp = CEXPR->getRHS();
    Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
    Expr *CONDExp = CEXPR->getCond();
    ConditionalOperator *CondExpr =
      new (Context) ConditionalOperator(CONDExp,
                                      SourceLocation(), cast<Expr>(LHSStmt),
                                      SourceLocation(), cast<Expr>(RHSStmt),
                                      Exp->getType(), VK_RValue, OK_Ordinary);
    return CondExpr;
  } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
    CPT = IRE->getType()->getAs<BlockPointerType>();
  } else if (const PseudoObjectExpr *POE
               = dyn_cast<PseudoObjectExpr>(BlockExp)) {
    CPT = POE->getType()->castAs<BlockPointerType>();
  } else {
    assert(1 && "RewriteBlockClass: Bad type");
  }
  assert(CPT && "RewriteBlockClass: Bad type");
  const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>();
  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, TTK_Struct, TUDecl,
                                      SourceLocation(), SourceLocation(),
                                      &Context->Idents.get("__block_impl"));
  QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));

  // Generate a funky cast.
  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 (!convertBlockPointerToFunctionPointer(t))
        convertToUnqualifiedObjCType(t);
      ArgTypes.push_back(t);
    }
  }
  // Now do the pointer to function cast.
  QualType PtrToFuncCastType
    = getSimpleFunctionType(Exp->getType(), &ArgTypes[0], ArgTypes.size());

  PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);

  CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
                                               CK_BitCast,
                                               const_cast<Expr*>(BlockExp));
  // 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(),
                                    SourceLocation(),
                                    &Context->Idents.get("FuncPtr"),
                                    Context->VoidPtrTy, 0,
                                    /*BitWidth=*/0, /*Mutable=*/true,
                                    ICIS_NoInit);
  MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
                                            FD->getType(), VK_LValue,
                                            OK_Ordinary);

  
  CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
                                                CK_BitCast, ME);
  PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast);

  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,
                                        Exp->getType(), VK_RValue,
                                        SourceLocation());
  return CE;
}

// We need to return the rewritten expression to handle cases where the
// DeclRefExpr is embedded in another expression being rewritten.
// For example:
//
// int main() {
//    __block Foo *f;
//    __block int i;
//
//    void (^myblock)() = ^() {
//        [f test]; // f is a DeclRefExpr embedded in a message (which is being rewritten).
//        i = 77;
//    };
//}
Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {
  // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
  // for each DeclRefExp where BYREFVAR is name of the variable.
  ValueDecl *VD = DeclRefExp->getDecl();
  bool isArrow = DeclRefExp->refersToEnclosingLocal();
  
  FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
                                    SourceLocation(),
                                    &Context->Idents.get("__forwarding"), 
                                    Context->VoidPtrTy, 0,
                                    /*BitWidth=*/0, /*Mutable=*/true,
                                    ICIS_NoInit);
  MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
                                            FD, SourceLocation(),
                                            FD->getType(), VK_LValue,
                                            OK_Ordinary);

  StringRef Name = VD->getName();
  FD = FieldDecl::Create(*Context, 0, SourceLocation(), SourceLocation(),
                         &Context->Idents.get(Name), 
                         Context->VoidPtrTy, 0,
                         /*BitWidth=*/0, /*Mutable=*/true,
                         ICIS_NoInit);
  ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
                                DeclRefExp->getType(), VK_LValue, OK_Ordinary);
  
  
  
  // Need parens to enforce precedence.
  ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 
                                          DeclRefExp->getExprLoc(), 
                                          ME);
  ReplaceStmt(DeclRefExp, PE);
  return PE;
}

// Rewrites the imported local variable V with external storage 
// (static, extern, etc.) as *V
//
Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
  ValueDecl *VD = DRE->getDecl();
  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
    if (!ImportedLocalExternalDecls.count(Var))
      return DRE;
  Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(),
                                          VK_LValue, OK_Ordinary,
                                          DRE->getLocation());
  // Need parens to enforce precedence.
  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
                                          Exp);
  ReplaceStmt(DRE, PE);
  return PE;
}

void RewriteModernObjC::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);
  QualType QT = CE->getType();
  const Type* TypePtr = QT->getAs<Type>();
  if (isa<TypeOfExprType>(TypePtr)) {
    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
    std::string TypeAsString = "(";
    RewriteBlockPointerType(TypeAsString, QT);
    TypeAsString += ")";
    ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
    return;
  }
  // advance the location to startArgList.
  const char *argPtr = startBuf;

  while (*argPtr++ && (argPtr < endBuf)) {
    switch (*argPtr) {
    case '^':
      // Replace the '^' with '*'.
      LocStart = LocStart.getLocWithOffset(argPtr-startBuf);
      ReplaceText(LocStart, 1, "*");
      break;
    }
  }
  return;
}

void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) {
  CastKind CastKind = IC->getCastKind();
  if (CastKind != CK_BlockPointerToObjCPointerCast &&
      CastKind != CK_AnyPointerToBlockPointerCast)
    return;
  
  QualType QT = IC->getType();
  (void)convertBlockPointerToFunctionPointer(QT);
  std::string TypeString(QT.getAsString(Context->getPrintingPolicy()));
  std::string Str = "(";
  Str += TypeString;
  Str += ")";
  InsertText(IC->getSubExpr()->getLocStart(), &Str[0], Str.size());

  return;
}

void RewriteModernObjC::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.getLocWithOffset(startArgList-startBuf);
  assert((DeclLoc.isValid()) && "Invalid DeclLoc");

  const char *argPtr = startArgList;

  while (*argPtr++ && parenCount) {
    switch (*argPtr) {
    case '^':
      // Replace the '^' with '*'.
      DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList);
      ReplaceText(DeclLoc, 1, "*");
      break;
    case '(':
      parenCount++;
      break;
    case ')':
      parenCount--;
      break;
    }
  }
  return;
}

bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
  const FunctionProtoType *FTP;
  const PointerType *PT = QT->getAs<PointerType>();
  if (PT) {
    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
  } else {
    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
  }
  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;
}

bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) {
  const FunctionProtoType *FTP;
  const PointerType *PT = QT->getAs<PointerType>();
  if (PT) {
    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
  } else {
    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
  }
  if (FTP) {
    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
         E = FTP->arg_type_end(); I != E; ++I) {
      if ((*I)->isObjCQualifiedIdType())
        return true;
      if ((*I)->isObjCObjectPointerType() &&
          (*I)->getPointeeType()->isObjCQualifiedInterfaceType())
        return true;
    }
        
  }
  return false;
}

void RewriteModernObjC::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 RewriteModernObjC::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 (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND))
    DeclT = TDD->getUnderlyingType();
  else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
    DeclT = FD->getType();
  else
    llvm_unreachable("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--;
  SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf);
  std::string buf;
  unsigned OrigLength=0;
  // *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.
    buf = '*';
    startBuf++;
    OrigLength++;
  }
  while (*startBuf != ')') {
    buf += *startBuf;
    startBuf++;
    OrigLength++;
  }
  buf += ')';
  OrigLength++;
  
  if (PointerTypeTakesAnyBlockArguments(DeclT) ||
      PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
    // Replace the '^' with '*' for arguments.
    // Replace id<P> with id/*<>*/
    DeclLoc = ND->getLocation();
    startBuf = SM->getCharacterData(DeclLoc);
    const char *argListBegin, *argListEnd;
    GetExtentOfArgList(startBuf, argListBegin, argListEnd);
    while (argListBegin < argListEnd) {
      if (*argListBegin == '^')
        buf += '*';
      else if (*argListBegin ==  '<') {
        buf += "/*"; 
        buf += *argListBegin++;
        OrigLength++;
        while (*argListBegin != '>') {
          buf += *argListBegin++;
          OrigLength++;
        }
        buf += *argListBegin;
        buf += "*/";
      }
      else
        buf += *argListBegin;
      argListBegin++;
      OrigLength++;
    }
    buf += ')';
    OrigLength++;
  }
  ReplaceText(Start, OrigLength, buf);
  
  return;
}


/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
///                    struct Block_byref_id_object *src) {
///  _Block_object_assign (&_dest->object, _src->object, 
///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
///                        [|BLOCK_FIELD_IS_WEAK]) // object
///  _Block_object_assign(&_dest->object, _src->object, 
///                       BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
///                       [|BLOCK_FIELD_IS_WEAK]) // block
/// }
/// And:
/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
///  _Block_object_dispose(_src->object, 
///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
///                        [|BLOCK_FIELD_IS_WEAK]) // object
///  _Block_object_dispose(_src->object, 
///                         BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
///                         [|BLOCK_FIELD_IS_WEAK]) // block
/// }

std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
                                                          int flag) {
  std::string S;
  if (CopyDestroyCache.count(flag))
    return S;
  CopyDestroyCache.insert(flag);
  S = "static void __Block_byref_id_object_copy_";
  S += utostr(flag);
  S += "(void *dst, void *src) {\n";
  
  // offset into the object pointer is computed as:
  // void * + void* + int + int + void* + void *
  unsigned IntSize = 
  static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
  unsigned VoidPtrSize = 
  static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
  
  unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
  S += " _Block_object_assign((char*)dst + ";
  S += utostr(offset);
  S += ", *(void * *) ((char*)src + ";
  S += utostr(offset);
  S += "), ";
  S += utostr(flag);
  S += ");\n}\n";
  
  S += "static void __Block_byref_id_object_dispose_";
  S += utostr(flag);
  S += "(void *src) {\n";
  S += " _Block_object_dispose(*(void * *) ((char*)src + ";
  S += utostr(offset);
  S += "), ";
  S += utostr(flag);
  S += ");\n}\n";
  return S;
}

/// RewriteByRefVar - For each __block typex ND variable this routine transforms
/// the declaration into:
/// struct __Block_byref_ND {
/// void *__isa;                  // NULL for everything except __weak pointers
/// struct __Block_byref_ND *__forwarding;
/// int32_t __flags;
/// int32_t __size;
/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
/// typex ND;
/// };
///
/// It then replaces declaration of ND variable with:
/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 
///                               __size=sizeof(struct __Block_byref_ND), 
///                               ND=initializer-if-any};
///
///
void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl,
                                        bool lastDecl) {
  int flag = 0;
  int isa = 0;
  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
  if (DeclLoc.isInvalid())
    // If type location is missing, it is because of missing type (a warning).
    // Use variable's location which is good for this case.
    DeclLoc = ND->getLocation();
  const char *startBuf = SM->getCharacterData(DeclLoc);
  SourceLocation X = ND->getLocEnd();
  X = SM->getExpansionLoc(X);
  const char *endBuf = SM->getCharacterData(X);
  std::string Name(ND->getNameAsString());
  std::string ByrefType;
  RewriteByRefString(ByrefType, Name, ND, true);
  ByrefType += " {\n";
  ByrefType += "  void *__isa;\n";
  RewriteByRefString(ByrefType, Name, ND);
  ByrefType += " *__forwarding;\n";
  ByrefType += " int __flags;\n";
  ByrefType += " int __size;\n";
  // Add void *__Block_byref_id_object_copy; 
  // void *__Block_byref_id_object_dispose; if needed.
  QualType Ty = ND->getType();
  bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty);
  if (HasCopyAndDispose) {
    ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n";
    ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n";
  }

  QualType T = Ty;
  (void)convertBlockPointerToFunctionPointer(T);
  T.getAsStringInternal(Name, Context->getPrintingPolicy());
    
  ByrefType += " " + Name + ";\n";
  ByrefType += "};\n";
  // Insert this type in global scope. It is needed by helper function.
  SourceLocation FunLocStart;
  if (CurFunctionDef)
     FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
  else {
    assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
    FunLocStart = CurMethodDef->getLocStart();
  }
  InsertText(FunLocStart, ByrefType);
  
  if (Ty.isObjCGCWeak()) {
    flag |= BLOCK_FIELD_IS_WEAK;
    isa = 1;
  }
  if (HasCopyAndDispose) {
    flag = BLOCK_BYREF_CALLER;
    QualType Ty = ND->getType();
    // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
    if (Ty->isBlockPointerType())
      flag |= BLOCK_FIELD_IS_BLOCK;
    else
      flag |= BLOCK_FIELD_IS_OBJECT;
    std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
    if (!HF.empty())
      InsertText(FunLocStart, HF);
  }
  
  // struct __Block_byref_ND ND = 
  // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 
  //  initializer-if-any};
  bool hasInit = (ND->getInit() != 0);
  // FIXME. rewriter does not support __block c++ objects which
  // require construction.
  if (hasInit)
    if (CXXConstructExpr *CExp = dyn_cast<CXXConstructExpr>(ND->getInit())) {
      CXXConstructorDecl *CXXDecl = CExp->getConstructor();
      if (CXXDecl && CXXDecl->isDefaultConstructor())
        hasInit = false;
    }
  
  unsigned flags = 0;
  if (HasCopyAndDispose)
    flags |= BLOCK_HAS_COPY_DISPOSE;
  Name = ND->getNameAsString();
  ByrefType.clear();
  RewriteByRefString(ByrefType, Name, ND);
  std::string ForwardingCastType("(");
  ForwardingCastType += ByrefType + " *)";
  ByrefType += " " + Name + " = {(void*)";
  ByrefType += utostr(isa);
  ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
  ByrefType += utostr(flags);
  ByrefType += ", ";
  ByrefType += "sizeof(";
  RewriteByRefString(ByrefType, Name, ND);
  ByrefType += ")";
  if (HasCopyAndDispose) {
    ByrefType += ", __Block_byref_id_object_copy_";
    ByrefType += utostr(flag);
    ByrefType += ", __Block_byref_id_object_dispose_";
    ByrefType += utostr(flag);
  }
  
  if (!firstDecl) {
    // In multiple __block declarations, and for all but 1st declaration,
    // find location of the separating comma. This would be start location
    // where new text is to be inserted.
    DeclLoc = ND->getLocation();
    const char *startDeclBuf = SM->getCharacterData(DeclLoc);
    const char *commaBuf = startDeclBuf;
    while (*commaBuf != ',')
      commaBuf--;
    assert((*commaBuf == ',') && "RewriteByRefVar: can't find ','");
    DeclLoc = DeclLoc.getLocWithOffset(commaBuf - startDeclBuf);
    startBuf = commaBuf;
  }
  
  if (!hasInit) {
    ByrefType += "};\n";
    unsigned nameSize = Name.size();
    // for block or function pointer declaration. Name is aleady
    // part of the declaration.
    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType())
      nameSize = 1;
    ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
  }
  else {
    ByrefType += ", ";
    SourceLocation startLoc;
    Expr *E = ND->getInit();
    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
      startLoc = ECE->getLParenLoc();
    else
      startLoc = E->getLocStart();
    startLoc = SM->getExpansionLoc(startLoc);
    endBuf = SM->getCharacterData(startLoc);
    ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);

    const char separator = lastDecl ? ';' : ',';
    const char *startInitializerBuf = SM->getCharacterData(startLoc);
    const char *separatorBuf = strchr(startInitializerBuf, separator);
    assert((*separatorBuf == separator) && 
           "RewriteByRefVar: can't find ';' or ','");
    SourceLocation separatorLoc =
      startLoc.getLocWithOffset(separatorBuf-startInitializerBuf);
    
    InsertText(separatorLoc, lastDecl ? "}" : "};\n");
  }
  return;
}

void RewriteModernObjC::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]->getDecl()->hasAttr<BlocksAttr>()) {
        if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
          BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
          BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
        }
      }
    // Unique all "by ref" declarations.
    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
        if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
          BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
          BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
        }
      }
    // Find any imported blocks...they will need special attention.
    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
          BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
          BlockDeclRefs[i]->getType()->isBlockPointerType())
        ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
  }
}

FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
  IdentifierInfo *ID = &Context->Idents.get(name);
  QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
  return FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
                              SourceLocation(), ID, FType, 0, SC_Extern,
                              SC_None, false, false);
}

Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
          const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs) {
  
  const BlockDecl *block = Exp->getBlockDecl();
  
  Blocks.push_back(Exp);

  CollectBlockDeclRefInfo(Exp);
  
  // Add inner imported variables now used in current block.
 int countOfInnerDecls = 0;
  if (!InnerBlockDeclRefs.empty()) {
    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
      DeclRefExpr *Exp = InnerBlockDeclRefs[i];
      ValueDecl *VD = Exp->getDecl();
      if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
      // We need to save the copied-in variables in nested
      // blocks because it is needed at the end for some of the API generations.
      // See SynthesizeBlockLiterals routine.
        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
        BlockDeclRefs.push_back(Exp);
        BlockByCopyDeclsPtrSet.insert(VD);
        BlockByCopyDecls.push_back(VD);
      }
      if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
        BlockDeclRefs.push_back(Exp);
        BlockByRefDeclsPtrSet.insert(VD);
        BlockByRefDecls.push_back(VD);
      }
    }
    // Find any imported blocks...they will need special attention.
    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
      if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
          InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
          InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
        ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
  }
  InnerDeclRefsCount.push_back(countOfInnerDecls);
  
  std::string FuncName;

  if (CurFunctionDef)
    FuncName = CurFunctionDef->getNameAsString();
  else if (CurMethodDef)
    BuildUniqueMethodName(FuncName, CurMethodDef);
  else if (GlobalVarDecl)
    FuncName = std::string(GlobalVarDecl->getNameAsString());

  bool GlobalBlockExpr = 
    block->getDeclContext()->getRedeclContext()->isFileContext();
  
  if (GlobalBlockExpr && !GlobalVarDecl) {
    Diags.Report(block->getLocation(), GlobalBlockRewriteFailedDiag);
    GlobalBlockExpr = false;
  }
  
  std::string BlockNumber = utostr(Blocks.size()-1);

  std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;

  // Get a pointer to the function type so we can cast appropriately.
  QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
  QualType FType = Context->getPointerType(BFT);

  FunctionDecl *FD;
  Expr *NewRep;

  // Simulate a contructor call...
  std::string Tag;
  
  if (GlobalBlockExpr)
    Tag = "__global_";
  else
    Tag = "__";
  Tag += FuncName + "_block_impl_" + BlockNumber;
  
  FD = SynthBlockInitFunctionDecl(Tag);
  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
                                               SourceLocation());

  SmallVector<Expr*, 4> InitExprs;

  // Initialize the block function.
  FD = SynthBlockInitFunctionDecl(Func);
  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
                                               VK_LValue, SourceLocation());
  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
                                                CK_BitCast, Arg);
  InitExprs.push_back(castExpr);

  // Initialize the block descriptor.
  std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA";

  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl,
                                   SourceLocation(), SourceLocation(),
                                   &Context->Idents.get(DescData.c_str()),
                                   Context->VoidPtrTy, 0,
                                   SC_Static, SC_None);
  UnaryOperator *DescRefExpr =
    new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
                                                          Context->VoidPtrTy,
                                                          VK_LValue,
                                                          SourceLocation()), 
                                UO_AddrOf,
                                Context->getPointerType(Context->VoidPtrTy), 
                                VK_RValue, OK_Ordinary,
                                SourceLocation());
  InitExprs.push_back(DescRefExpr); 
  
  // Add initializers for any closure decl refs.
  if (BlockDeclRefs.size()) {
    Expr *Exp;
    // Output all "by copy" declarations.
    for (SmallVector<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)->getName());
        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
                                        VK_LValue, SourceLocation());
        if (HasLocalVariableExternalStorage(*I)) {
          QualType QT = (*I)->getType();
          QT = Context->getPointerType(QT);
          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
                                            OK_Ordinary, SourceLocation());
        }
      } else if (isTopLevelBlockPointerType((*I)->getType())) {
        FD = SynthBlockInitFunctionDecl((*I)->getName());
        Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
                                        VK_LValue, SourceLocation());
        Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
                                       CK_BitCast, Arg);
      } else {
        FD = SynthBlockInitFunctionDecl((*I)->getName());
        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
                                        VK_LValue, SourceLocation());
        if (HasLocalVariableExternalStorage(*I)) {
          QualType QT = (*I)->getType();
          QT = Context->getPointerType(QT);
          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
                                            OK_Ordinary, SourceLocation());
        }
        
      }
      InitExprs.push_back(Exp);
    }
    // Output all "by ref" declarations.
    for (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
         E = BlockByRefDecls.end(); I != E; ++I) {
      ValueDecl *ND = (*I);
      std::string Name(ND->getNameAsString());
      std::string RecName;
      RewriteByRefString(RecName, Name, ND, true);
      IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 
                                                + sizeof("struct"));
      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                          SourceLocation(), SourceLocation(),
                                          II);
      assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
      
      FD = SynthBlockInitFunctionDecl((*I)->getName());
      Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
                                      SourceLocation());
      bool isNestedCapturedVar = false;
      if (block)
        for (BlockDecl::capture_const_iterator ci = block->capture_begin(),
             ce = block->capture_end(); ci != ce; ++ci) {
          const VarDecl *variable = ci->getVariable();
          if (variable == ND && ci->isNested()) {
            assert (ci->isByRef() && 
                    "SynthBlockInitExpr - captured block variable is not byref");
            isNestedCapturedVar = true;
            break;
          }
        }
      // captured nested byref variable has its address passed. Do not take
      // its address again.
      if (!isNestedCapturedVar)
          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf,
                                     Context->getPointerType(Exp->getType()),
                                     VK_RValue, OK_Ordinary, SourceLocation());
      Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
      InitExprs.push_back(Exp);
    }
  }
  if (ImportedBlockDecls.size()) {
    // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
    int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR);
    unsigned IntSize = 
      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
    Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 
                                           Context->IntTy, SourceLocation());
    InitExprs.push_back(FlagExp);
  }
  NewRep = new (Context) CallExpr(*Context, DRE, InitExprs,
                                  FType, VK_LValue, SourceLocation());
  
  if (GlobalBlockExpr) {
    assert (GlobalConstructionExp == 0 && 
            "SynthBlockInitExpr - GlobalConstructionExp must be null");
    GlobalConstructionExp = NewRep;
    NewRep = DRE;
  }
  
  NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
                             Context->getPointerType(NewRep->getType()),
                             VK_RValue, OK_Ordinary, SourceLocation());
  NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
                                    NewRep);
  BlockDeclRefs.clear();
  BlockByRefDecls.clear();
  BlockByRefDeclsPtrSet.clear();
  BlockByCopyDecls.clear();
  BlockByCopyDeclsPtrSet.clear();
  ImportedBlockDecls.clear();
  return NewRep;
}

bool RewriteModernObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) {
  if (const ObjCForCollectionStmt * CS = 
      dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
        return CS->getElement() == DS;
  return false;
}

//===----------------------------------------------------------------------===//
// Function Body / Expression rewriting
//===----------------------------------------------------------------------===//

Stmt *RewriteModernObjC::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);
  }

  // Pseudo-object operations and ivar references need special
  // treatment because we're going to recursively rewrite them.
  if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) {
    if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) {
      return RewritePropertyOrImplicitSetter(PseudoOp);
    } else {
      return RewritePropertyOrImplicitGetter(PseudoOp);
    }
  } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
    return RewriteObjCIvarRefExpr(IvarRefExpr);
  }

  SourceRange OrigStmtRange = S->getSourceRange();

  // Perform a bottom up rewrite of all children.
  for (Stmt::child_range CI = S->children(); CI; ++CI)
    if (*CI) {
      Stmt *childStmt = (*CI);
      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
      if (newStmt) {
        *CI = newStmt;
      }
    }

  if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
    SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
    llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
    InnerContexts.insert(BE->getBlockDecl());
    ImportedLocalExternalDecls.clear();
    GetInnerBlockDeclRefExprs(BE->getBody(),
                              InnerBlockDeclRefs, InnerContexts);
    // Rewrite the block body in place.
    Stmt *SaveCurrentBody = CurrentBody;
    CurrentBody = BE->getBody();
    PropParentMap = 0;
    // block literal on rhs of a property-dot-sytax assignment
    // must be replaced by its synthesize ast so getRewrittenText
    // works as expected. In this case, what actually ends up on RHS
    // is the blockTranscribed which is the helper function for the
    // block literal; as in: self.c = ^() {[ace ARR];};
    bool saveDisableReplaceStmt = DisableReplaceStmt;
    DisableReplaceStmt = false;
    RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
    DisableReplaceStmt = saveDisableReplaceStmt;
    CurrentBody = SaveCurrentBody;
    PropParentMap = 0;
    ImportedLocalExternalDecls.clear();
    // Now we snarf the rewritten text and stash it away for later use.
    std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
    RewrittenBlockExprs[BE] = Str;

    Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
                            
    //blockTranscribed->dump();
    ReplaceStmt(S, blockTranscribed);
    return blockTranscribed;
  }
  // Handle specific things.
  if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
    return RewriteAtEncode(AtEncode);

  if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
    return RewriteAtSelector(AtSelector);

  if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
    return RewriteObjCStringLiteral(AtString);
  
  if (ObjCBoolLiteralExpr *BoolLitExpr = dyn_cast<ObjCBoolLiteralExpr>(S))
    return RewriteObjCBoolLiteralExpr(BoolLitExpr);
  
  if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(S))
    return RewriteObjCBoxedExpr(BoxedExpr);
  
  if (ObjCArrayLiteral *ArrayLitExpr = dyn_cast<ObjCArrayLiteral>(S))
    return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
  
  if (ObjCDictionaryLiteral *DictionaryLitExpr = 
        dyn_cast<ObjCDictionaryLiteral>(S))
    return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);

  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 (ObjCAutoreleasePoolStmt *StmtAutoRelease = 
        dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
    return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
  }
  
  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.
    // NOTE: We need to avoid rewriting the DeclStmt if it is within
    // the context of an ObjCForCollectionStmt. For example:
    //   NSArray *someArray;
    //   for (id <FooProtocol> index in someArray) ;
    // This is because RewriteObjCForCollectionStmt() does textual rewriting 
    // and it depends on the original text locations/positions.
    if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
      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 (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
          if (VD->hasAttr<BlocksAttr>()) {
            static unsigned uniqueByrefDeclCount = 0;
            assert(!BlockByRefDeclNo.count(ND) &&
              "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
            BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
            RewriteByRefVar(VD, (DI == DS->decl_begin()), ((DI+1) == DE));
          }
          else           
            RewriteTypeOfDecl(VD);
        }
      }
      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(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 (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
    ValueDecl *VD = DRE->getDecl(); 
    if (VD->hasAttr<BlocksAttr>())
      return RewriteBlockDeclRefExpr(DRE);
    if (HasLocalVariableExternalStorage(VD))
      return RewriteLocalVariableExternalStorage(DRE);
  }
  
  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
    if (CE->getCallee()->getType()->isBlockPointerType()) {
      Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
      ReplaceStmt(S, BlockCall);
      return BlockCall;
    }
  }
  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) {
    RewriteCastExpr(CE);
  }
  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
    RewriteImplicitCastObjCExpr(ICE);
  }
#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;
}

void RewriteModernObjC::RewriteRecordBody(RecordDecl *RD) {
  for (RecordDecl::field_iterator i = RD->field_begin(), 
                                  e = RD->field_end(); i != e; ++i) {
    FieldDecl *FD = *i;
    if (isTopLevelBlockPointerType(FD->getType()))
      RewriteBlockPointerDecl(FD);
    if (FD->getType()->isObjCQualifiedIdType() ||
        FD->getType()->isObjCQualifiedInterfaceType())
      RewriteObjCQualifiedInterfaceTypes(FD);
  }
}

/// HandleDeclInMainFile - This is called for each top-level decl defined in the
/// main file of the input.
void RewriteModernObjC::HandleDeclInMainFile(Decl *D) {
  switch (D->getKind()) {
    case Decl::Function: {
      FunctionDecl *FD = 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);

      if (!FD->isThisDeclarationADefinition())
        break;

      // FIXME: If this should support Obj-C++, support CXXTryStmt
      if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
        CurFunctionDef = FD;
        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);
        RewriteLineDirective(D);
        CurFunctionDef = 0;
      }
      break;
    }
    case Decl::ObjCMethod: {
      ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
      if (CompoundStmt *Body = MD->getCompoundBody()) {
        CurMethodDef = MD;
        CurrentBody = Body;
        Body =
          cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
        MD->setBody(Body);
        CurrentBody = 0;
        if (PropParentMap) {
          delete PropParentMap;
          PropParentMap = 0;
        }
        InsertBlockLiteralsWithinMethod(MD);
        RewriteLineDirective(D);
        CurMethodDef = 0;
      }
      break;
    }
    case Decl::ObjCImplementation: {
      ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D);
      ClassImplementation.push_back(CI);
      break;
    }
    case Decl::ObjCCategoryImpl: {
      ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D);
      CategoryImplementation.push_back(CI);
      break;
    }
    case Decl::Var: {
      VarDecl *VD = 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);
          }
        }
      } else if (VD->getType()->isRecordType()) {
        RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl();
        if (RD->isCompleteDefinition())
          RewriteRecordBody(RD);
      }
      if (VD->getInit()) {
        GlobalVarDecl = VD;
        CurrentBody = VD->getInit();
        RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
        CurrentBody = 0;
        if (PropParentMap) {
          delete PropParentMap;
          PropParentMap = 0;
        }
        SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName());
        GlobalVarDecl = 0;
          
        // This is needed for blocks.
        if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
            RewriteCastExpr(CE);
        }
      }
      break;
    }
    case Decl::TypeAlias:
    case Decl::Typedef: {
      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
          RewriteBlockPointerDecl(TD);
        else if (TD->getUnderlyingType()->isFunctionPointerType())
          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
      }
      break;
    }
    case Decl::CXXRecord:
    case Decl::Record: {
      RecordDecl *RD = cast<RecordDecl>(D);
      if (RD->isCompleteDefinition()) 
        RewriteRecordBody(RD);
      break;
    }
    default:
      break;
  }
  // Nothing yet.
}

/// Write_ProtocolExprReferencedMetadata - This routine writer out the
/// protocol reference symbols in the for of:
/// struct _protocol_t *PROTOCOL_REF = &PROTOCOL_METADATA.
static void Write_ProtocolExprReferencedMetadata(ASTContext *Context, 
                                                 ObjCProtocolDecl *PDecl,
                                                 std::string &Result) {
  // Also output .objc_protorefs$B section and its meta-data.
  if (Context->getLangOpts().MicrosoftExt)
    Result += "static ";
  Result += "struct _protocol_t *";
  Result += "_OBJC_PROTOCOL_REFERENCE_$_";
  Result += PDecl->getNameAsString();
  Result += " = &";
  Result += "_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
  Result += ";\n";
}

void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) {
  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);
    Write_ProtocolExprReferencedMetadata(Context, (*I), Preamble);
  }

  InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
  
  if (ClassImplementation.size() || CategoryImplementation.size())
    RewriteImplementations();
  
  for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
    ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
    // Write struct declaration for the class matching its ivar declarations.
    // Note that for modern abi, this is postponed until the end of TU
    // because class extensions and the implementation might declare their own
    // private ivars.
    RewriteInterfaceDecl(CDecl);
  }

  // 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 {
    llvm::errs() << "No changes\n";
  }

  if (ClassImplementation.size() || CategoryImplementation.size() ||
      ProtocolExprDecls.size()) {
    // Rewrite Objective-c meta data*
    std::string ResultStr;
    RewriteMetaDataIntoBuffer(ResultStr);
    // Emit metadata.
    *OutFile << ResultStr;
  }
  // Emit ImageInfo;
  {
    std::string ResultStr;
    WriteImageInfo(ResultStr);
    *OutFile << ResultStr;
  }
  OutFile->flush();
}

void RewriteModernObjC::Initialize(ASTContext &context) {
  InitializeCommon(context);
  
  Preamble += "#ifndef __OBJC2__\n";
  Preamble += "#define __OBJC2__\n";
  Preamble += "#endif\n";

  // 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 { \n\tstruct objc_object *object; ";
  Preamble += "\n\tstruct objc_object *superClass; ";
  // Add a constructor for creating temporary objects.
  Preamble += "\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
  Preamble += ": object(o), superClass(s) {} ";
  Preamble += "\n};\n";
  
  if (LangOpts.MicrosoftExt) {
    // Define all sections using syntax that makes sense.
    // These are currently generated.
    Preamble += "\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
    Preamble += "#pragma section(\".objc_catlist$B\", long, read, write)\n";
    Preamble += "#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
    Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
    Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
    // These are generated but not necessary for functionality.
    Preamble += "#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
    Preamble += "#pragma section(\".inst_meth$B\", long, read, write)\n";
    Preamble += "#pragma section(\".cls_meth$B\", long, read, write)\n";
    Preamble += "#pragma section(\".objc_ivar$B\", long, read, write)\n";
    
    // These need be generated for performance. Currently they are not,
    // using API calls instead.
    Preamble += "#pragma section(\".objc_selrefs$B\", long, read, write)\n";
    Preamble += "#pragma section(\".objc_classrefs$B\", long, read, write)\n";
    Preamble += "#pragma section(\".objc_superrefs$B\", long, read, write)\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.MicrosoftExt) {
    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 void objc_msgSend(void);\n";
  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";

  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
  Preamble += "(const char *);\n";
  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
  Preamble += "(struct objc_class *);\n";
  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
  Preamble += "(const char *);\n";
  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
  // @synchronized hooks.
  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
  Preamble += "__OBJC_RW_DLLIMPORT int 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 Reserved;\n";
  Preamble += "  void *FuncPtr;\n";
  Preamble += "};\n";
  Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
  Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n";
  Preamble += "extern \"C\" __declspec(dllexport) "
  "void _Block_object_assign(void *, const void *, const int);\n";
  Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
  Preamble += "#else\n";
  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
  Preamble += "#endif\n";
  Preamble += "#endif\n";
  if (LangOpts.MicrosoftExt) {
    Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
    Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
    Preamble += "#ifndef KEEP_ATTRIBUTES\n";  // We use this for clang tests.
    Preamble += "#define __attribute__(X)\n";
    Preamble += "#endif\n";
    Preamble += "#ifndef __weak\n";
    Preamble += "#define __weak\n";
    Preamble += "#endif\n";
    Preamble += "#ifndef __block\n";
    Preamble += "#define __block\n";
    Preamble += "#endif\n";
  }
  else {
    Preamble += "#define __block\n";
    Preamble += "#define __weak\n";
  }
  
  // Declarations required for modern objective-c array and dictionary literals.
  Preamble += "\n#include <stdarg.h>\n";
  Preamble += "struct __NSContainer_literal {\n";
  Preamble += "  void * *arr;\n";
  Preamble += "  __NSContainer_literal (unsigned int count, ...) {\n";
  Preamble += "\tva_list marker;\n";
  Preamble += "\tva_start(marker, count);\n";
  Preamble += "\tarr = new void *[count];\n";
  Preamble += "\tfor (unsigned i = 0; i < count; i++)\n";
  Preamble += "\t  arr[i] = va_arg(marker, void *);\n";
  Preamble += "\tva_end( marker );\n";
  Preamble += "  };\n";
  Preamble += "  ~__NSContainer_literal() {\n";
  Preamble += "\tdelete[] arr;\n";
  Preamble += "  }\n";
  Preamble += "};\n";
  
  // Declaration required for implementation of @autoreleasepool statement.
  Preamble += "extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
  Preamble += "extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
  Preamble += "struct __AtAutoreleasePool {\n";
  Preamble += "  __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
  Preamble += "  ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
  Preamble += "  void * atautoreleasepoolobj;\n";
  Preamble += "};\n";
  
  // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
  // as this avoids warning in any 64bit/32bit compilation model.
  Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
}

/// RewriteIvarOffsetComputation - This rutine synthesizes computation of
/// ivar offset.
void RewriteModernObjC::RewriteIvarOffsetComputation(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 += ivar->getContainingInterface()->getNameAsString();
    if (LangOpts.MicrosoftExt)
      Result += "_IMPL";
    Result += ", ";
    Result += ivar->getNameAsString();
    Result += ")";
  }
}

/// WriteModernMetadataDeclarations - Writes out metadata declarations for modern ABI.
/// struct _prop_t {
///   const char *name;
///   char *attributes;
/// }

/// struct _prop_list_t {
///   uint32_t entsize;      // sizeof(struct _prop_t)
///   uint32_t count_of_properties;
///   struct _prop_t prop_list[count_of_properties];
/// }

/// struct _protocol_t;

/// struct _protocol_list_t {
///   long protocol_count;   // Note, this is 32/64 bit
///   struct _protocol_t * protocol_list[protocol_count];
/// }

/// struct _objc_method {
///   SEL _cmd;
///   const char *method_type;
///   char *_imp;
/// }

/// struct _method_list_t {
///   uint32_t entsize;  // sizeof(struct _objc_method)
///   uint32_t method_count;
///   struct _objc_method method_list[method_count];
/// }

/// struct _protocol_t {
///   id isa;  // NULL
///   const char *protocol_name;
///   const struct _protocol_list_t * protocol_list; // super protocols
///   const struct method_list_t *instance_methods;
///   const struct method_list_t *class_methods;
///   const struct method_list_t *optionalInstanceMethods;
///   const struct method_list_t *optionalClassMethods;
///   const struct _prop_list_t * properties;
///   const uint32_t size;  // sizeof(struct _protocol_t)
///   const uint32_t flags;  // = 0
///   const char ** extendedMethodTypes;
/// }

/// struct _ivar_t {
///   unsigned long int *offset;  // pointer to ivar offset location
///   const char *name;
///   const char *type;
///   uint32_t alignment;
///   uint32_t size;
/// }

/// struct _ivar_list_t {
///   uint32 entsize;  // sizeof(struct _ivar_t)
///   uint32 count;
///   struct _ivar_t list[count];
/// }

/// struct _class_ro_t {
///   uint32_t flags;
///   uint32_t instanceStart;
///   uint32_t instanceSize;
///   uint32_t reserved;  // only when building for 64bit targets
///   const uint8_t *ivarLayout;
///   const char *name;
///   const struct _method_list_t *baseMethods;
///   const struct _protocol_list_t *baseProtocols;
///   const struct _ivar_list_t *ivars;
///   const uint8_t *weakIvarLayout;
///   const struct _prop_list_t *properties;
/// }

/// struct _class_t {
///   struct _class_t *isa;
///   struct _class_t *superclass;
///   void *cache;
///   IMP *vtable;
///   struct _class_ro_t *ro;
/// }

/// struct _category_t {
///   const char *name;
///   struct _class_t *cls;
///   const struct _method_list_t *instance_methods;
///   const struct _method_list_t *class_methods;
///   const struct _protocol_list_t *protocols;
///   const struct _prop_list_t *properties;
/// }

/// MessageRefTy - LLVM for:
/// struct _message_ref_t {
///   IMP messenger;
///   SEL name;
/// };

/// SuperMessageRefTy - LLVM for:
/// struct _super_message_ref_t {
///   SUPER_IMP messenger;
///   SEL name;
/// };

static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result) {
  static bool meta_data_declared = false;
  if (meta_data_declared)
    return;
  
  Result += "\nstruct _prop_t {\n";
  Result += "\tconst char *name;\n";
  Result += "\tconst char *attributes;\n";
  Result += "};\n";
  
  Result += "\nstruct _protocol_t;\n";
  
  Result += "\nstruct _objc_method {\n";
  Result += "\tstruct objc_selector * _cmd;\n";
  Result += "\tconst char *method_type;\n";
  Result += "\tvoid  *_imp;\n";
  Result += "};\n";
  
  Result += "\nstruct _protocol_t {\n";
  Result += "\tvoid * isa;  // NULL\n";
  Result += "\tconst char *protocol_name;\n";
  Result += "\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
  Result += "\tconst struct method_list_t *instance_methods;\n";
  Result += "\tconst struct method_list_t *class_methods;\n";
  Result += "\tconst struct method_list_t *optionalInstanceMethods;\n";
  Result += "\tconst struct method_list_t *optionalClassMethods;\n";
  Result += "\tconst struct _prop_list_t * properties;\n";
  Result += "\tconst unsigned int size;  // sizeof(struct _protocol_t)\n";
  Result += "\tconst unsigned int flags;  // = 0\n";
  Result += "\tconst char ** extendedMethodTypes;\n";
  Result += "};\n";
  
  Result += "\nstruct _ivar_t {\n";
  Result += "\tunsigned long int *offset;  // pointer to ivar offset location\n";
  Result += "\tconst char *name;\n";
  Result += "\tconst char *type;\n";
  Result += "\tunsigned int alignment;\n";
  Result += "\tunsigned int  size;\n";
  Result += "};\n";
  
  Result += "\nstruct _class_ro_t {\n";
  Result += "\tunsigned int flags;\n";
  Result += "\tunsigned int instanceStart;\n";
  Result += "\tunsigned int instanceSize;\n";
  const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
  if (Triple.getArch() == llvm::Triple::x86_64)
    Result += "\tunsigned int reserved;\n";
  Result += "\tconst unsigned char *ivarLayout;\n";
  Result += "\tconst char *name;\n";
  Result += "\tconst struct _method_list_t *baseMethods;\n";
  Result += "\tconst struct _objc_protocol_list *baseProtocols;\n";
  Result += "\tconst struct _ivar_list_t *ivars;\n";
  Result += "\tconst unsigned char *weakIvarLayout;\n";
  Result += "\tconst struct _prop_list_t *properties;\n";
  Result += "};\n";
  
  Result += "\nstruct _class_t {\n";
  Result += "\tstruct _class_t *isa;\n";
  Result += "\tstruct _class_t *superclass;\n";
  Result += "\tvoid *cache;\n";
  Result += "\tvoid *vtable;\n";
  Result += "\tstruct _class_ro_t *ro;\n";
  Result += "};\n";
  
  Result += "\nstruct _category_t {\n";
  Result += "\tconst char *name;\n";
  Result += "\tstruct _class_t *cls;\n";
  Result += "\tconst struct _method_list_t *instance_methods;\n";
  Result += "\tconst struct _method_list_t *class_methods;\n";
  Result += "\tconst struct _protocol_list_t *protocols;\n";
  Result += "\tconst struct _prop_list_t *properties;\n";
  Result += "};\n";
  
  Result += "extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
  Result += "#pragma warning(disable:4273)\n";
  meta_data_declared = true;
}

static void Write_protocol_list_t_TypeDecl(std::string &Result,
                                           long super_protocol_count) {
  Result += "struct /*_protocol_list_t*/"; Result += " {\n";
  Result += "\tlong protocol_count;  // Note, this is 32/64 bit\n";
  Result += "\tstruct _protocol_t *super_protocols[";
  Result += utostr(super_protocol_count); Result += "];\n";
  Result += "}";
}

static void Write_method_list_t_TypeDecl(std::string &Result,
                                         unsigned int method_count) {
  Result += "struct /*_method_list_t*/"; Result += " {\n";
  Result += "\tunsigned int entsize;  // sizeof(struct _objc_method)\n";
  Result += "\tunsigned int method_count;\n";
  Result += "\tstruct _objc_method method_list[";
  Result += utostr(method_count); Result += "];\n";
  Result += "}";
}

static void Write__prop_list_t_TypeDecl(std::string &Result,
                                        unsigned int property_count) {
  Result += "struct /*_prop_list_t*/"; Result += " {\n";
  Result += "\tunsigned int entsize;  // sizeof(struct _prop_t)\n";
  Result += "\tunsigned int count_of_properties;\n";
  Result += "\tstruct _prop_t prop_list[";
  Result += utostr(property_count); Result += "];\n";
  Result += "}";
}

static void Write__ivar_list_t_TypeDecl(std::string &Result,
                                        unsigned int ivar_count) {
  Result += "struct /*_ivar_list_t*/"; Result += " {\n";
  Result += "\tunsigned int entsize;  // sizeof(struct _prop_t)\n";
  Result += "\tunsigned int count;\n";
  Result += "\tstruct _ivar_t ivar_list[";
  Result += utostr(ivar_count); Result += "];\n";
  Result += "}";
}

static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result,
                                            ArrayRef<ObjCProtocolDecl *> SuperProtocols,
                                            StringRef VarName,
                                            StringRef ProtocolName) {
  if (SuperProtocols.size() > 0) {
    Result += "\nstatic ";
    Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
    Result += " "; Result += VarName;
    Result += ProtocolName; 
    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
    Result += "\t"; Result += utostr(SuperProtocols.size()); Result += ",\n";
    for (unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
      ObjCProtocolDecl *SuperPD = SuperProtocols[i];
      Result += "\t&"; Result += "_OBJC_PROTOCOL_"; 
      Result += SuperPD->getNameAsString();
      if (i == e-1)
        Result += "\n};\n";
      else
        Result += ",\n";
    }
  }
}

static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
                                            ASTContext *Context, std::string &Result,
                                            ArrayRef<ObjCMethodDecl *> Methods,
                                            StringRef VarName,
                                            StringRef TopLevelDeclName,
                                            bool MethodImpl) {
  if (Methods.size() > 0) {
    Result += "\nstatic ";
    Write_method_list_t_TypeDecl(Result, Methods.size());
    Result += " "; Result += VarName;
    Result += TopLevelDeclName; 
    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
    Result += "\t"; Result += "sizeof(_objc_method)"; Result += ",\n";
    Result += "\t"; Result += utostr(Methods.size()); Result += ",\n";
    for (unsigned i = 0, e = Methods.size(); i < e; i++) {
      ObjCMethodDecl *MD = Methods[i];
      if (i == 0)
        Result += "\t{{(struct objc_selector *)\"";
      else
        Result += "\t{(struct objc_selector *)\"";
      Result += (MD)->getSelector().getAsString(); Result += "\"";
      Result += ", ";
      std::string MethodTypeString;
      Context->getObjCEncodingForMethodDecl(MD, MethodTypeString);
      Result += "\""; Result += MethodTypeString; Result += "\"";
      Result += ", ";
      if (!MethodImpl)
        Result += "0";
      else {
        Result += "(void *)";
        Result += RewriteObj.MethodInternalNames[MD];
      }
      if (i  == e-1)
        Result += "}}\n";
      else
        Result += "},\n";
    }
    Result += "};\n";
  }
}

static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
                                           ASTContext *Context, std::string &Result,
                                           ArrayRef<ObjCPropertyDecl *> Properties,
                                           const Decl *Container,
                                           StringRef VarName,
                                           StringRef ProtocolName) {
  if (Properties.size() > 0) {
    Result += "\nstatic ";
    Write__prop_list_t_TypeDecl(Result, Properties.size());
    Result += " "; Result += VarName;
    Result += ProtocolName; 
    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
    Result += "\t"; Result += "sizeof(_prop_t)"; Result += ",\n";
    Result += "\t"; Result += utostr(Properties.size()); Result += ",\n";
    for (unsigned i = 0, e = Properties.size(); i < e; i++) {
      ObjCPropertyDecl *PropDecl = Properties[i];
      if (i == 0)
        Result += "\t{{\"";
      else
        Result += "\t{\"";
      Result += PropDecl->getName(); Result += "\",";
      std::string PropertyTypeString, QuotePropertyTypeString;
      Context->getObjCEncodingForPropertyDecl(PropDecl, Container, PropertyTypeString);
      RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
      Result += "\""; Result += QuotePropertyTypeString; Result += "\"";
      if (i  == e-1)
        Result += "}}\n";
      else
        Result += "},\n";
    }
    Result += "};\n";
  }
}

// Metadata flags
enum MetaDataDlags {
  CLS = 0x0,
  CLS_META = 0x1,
  CLS_ROOT = 0x2,
  OBJC2_CLS_HIDDEN = 0x10,
  CLS_EXCEPTION = 0x20,
  
  /// (Obsolete) ARC-specific: this class has a .release_ivars method
  CLS_HAS_IVAR_RELEASER = 0x40,
  /// class was compiled with -fobjc-arr
  CLS_COMPILED_BY_ARC = 0x80  // (1<<7)
};

static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result, 
                                          unsigned int flags, 
                                          const std::string &InstanceStart, 
                                          const std::string &InstanceSize,
                                          ArrayRef<ObjCMethodDecl *>baseMethods,
                                          ArrayRef<ObjCProtocolDecl *>baseProtocols,
                                          ArrayRef<ObjCIvarDecl *>ivars,
                                          ArrayRef<ObjCPropertyDecl *>Properties,
                                          StringRef VarName,
                                          StringRef ClassName) {
  Result += "\nstatic struct _class_ro_t ";
  Result += VarName; Result += ClassName;
  Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
  Result += "\t"; 
  Result += llvm::utostr(flags); Result += ", "; 
  Result += InstanceStart; Result += ", ";
  Result += InstanceSize; Result += ", \n";
  Result += "\t";
  const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
  if (Triple.getArch() == llvm::Triple::x86_64)
    // uint32_t const reserved; // only when building for 64bit targets
    Result += "(unsigned int)0, \n\t";
  // const uint8_t * const ivarLayout;
  Result += "0, \n\t";
  Result += "\""; Result += ClassName; Result += "\",\n\t";
  bool metaclass = ((flags & CLS_META) != 0);
  if (baseMethods.size() > 0) {
    Result += "(const struct _method_list_t *)&";
    if (metaclass)
      Result += "_OBJC_$_CLASS_METHODS_";
    else
      Result += "_OBJC_$_INSTANCE_METHODS_";
    Result += ClassName;
    Result += ",\n\t";
  }
  else
    Result += "0, \n\t";

  if (!metaclass && baseProtocols.size() > 0) {
    Result += "(const struct _objc_protocol_list *)&";
    Result += "_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
    Result += ",\n\t";
  }
  else
    Result += "0, \n\t";

  if (!metaclass && ivars.size() > 0) {
    Result += "(const struct _ivar_list_t *)&";
    Result += "_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
    Result += ",\n\t";
  }
  else
    Result += "0, \n\t";

  // weakIvarLayout
  Result += "0, \n\t";
  if (!metaclass && Properties.size() > 0) {
    Result += "(const struct _prop_list_t *)&";
    Result += "_OBJC_$_PROP_LIST_"; Result += ClassName;
    Result += ",\n";
  }
  else
    Result += "0, \n";

  Result += "};\n";
}

static void Write_class_t(ASTContext *Context, std::string &Result,
                          StringRef VarName,
                          const ObjCInterfaceDecl *CDecl, bool metaclass) {
  bool rootClass = (!CDecl->getSuperClass());
  const ObjCInterfaceDecl *RootClass = CDecl;
  
  if (!rootClass) {
    // Find the Root class
    RootClass = CDecl->getSuperClass();
    while (RootClass->getSuperClass()) {
      RootClass = RootClass->getSuperClass();
    }
  }

  if (metaclass && rootClass) {
    // Need to handle a case of use of forward declaration.
    Result += "\n";
    Result += "extern \"C\" ";
    if (CDecl->getImplementation())
      Result += "__declspec(dllexport) ";
    else
      Result += "__declspec(dllimport) ";
    
    Result += "struct _class_t OBJC_CLASS_$_";
    Result += CDecl->getNameAsString();
    Result += ";\n";
  }
  // Also, for possibility of 'super' metadata class not having been defined yet.
  if (!rootClass) {
    ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
    Result += "\n";
    Result += "extern \"C\" ";
    if (SuperClass->getImplementation())
      Result += "__declspec(dllexport) ";
    else
      Result += "__declspec(dllimport) ";

    Result += "struct _class_t "; 
    Result += VarName;
    Result += SuperClass->getNameAsString();
    Result += ";\n";
    
    if (metaclass && RootClass != SuperClass) {
      Result += "extern \"C\" ";
      if (RootClass->getImplementation())
        Result += "__declspec(dllexport) ";
      else
        Result += "__declspec(dllimport) ";

      Result += "struct _class_t "; 
      Result += VarName;
      Result += RootClass->getNameAsString();
      Result += ";\n";
    }
  }
  
  Result += "\nextern \"C\" __declspec(dllexport) struct _class_t "; 
  Result += VarName; Result += CDecl->getNameAsString();
  Result += " __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
  Result += "\t";
  if (metaclass) {
    if (!rootClass) {
      Result += "0, // &"; Result += VarName;
      Result += RootClass->getNameAsString();
      Result += ",\n\t";
      Result += "0, // &"; Result += VarName;
      Result += CDecl->getSuperClass()->getNameAsString();
      Result += ",\n\t";
    }
    else {
      Result += "0, // &"; Result += VarName; 
      Result += CDecl->getNameAsString();
      Result += ",\n\t";
      Result += "0, // &OBJC_CLASS_$_"; Result += CDecl->getNameAsString();
      Result += ",\n\t";
    }
  }
  else {
    Result += "0, // &OBJC_METACLASS_$_"; 
    Result += CDecl->getNameAsString();
    Result += ",\n\t";
    if (!rootClass) {
      Result += "0, // &"; Result += VarName;
      Result += CDecl->getSuperClass()->getNameAsString();
      Result += ",\n\t";
    }
    else 
      Result += "0,\n\t";
  }
  Result += "0, // (void *)&_objc_empty_cache,\n\t";
  Result += "0, // unused, was (void *)&_objc_empty_vtable,\n\t";
  if (metaclass)
    Result += "&_OBJC_METACLASS_RO_$_";
  else
    Result += "&_OBJC_CLASS_RO_$_";
  Result += CDecl->getNameAsString();
  Result += ",\n};\n";
  
  // Add static function to initialize some of the meta-data fields.
  // avoid doing it twice.
  if (metaclass)
    return;
  
  const ObjCInterfaceDecl *SuperClass = 
    rootClass ? CDecl : CDecl->getSuperClass();
  
  Result += "static void OBJC_CLASS_SETUP_$_";
  Result += CDecl->getNameAsString();
  Result += "(void ) {\n";
  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
  Result += ".isa = "; Result += "&OBJC_METACLASS_$_";
  Result += RootClass->getNameAsString(); Result += ";\n";
  
  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
  Result += ".superclass = ";
  if (rootClass)
    Result += "&OBJC_CLASS_$_";
  else
     Result += "&OBJC_METACLASS_$_";

  Result += SuperClass->getNameAsString(); Result += ";\n";
  
  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
  Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n";
  
  Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
  Result += ".isa = "; Result += "&OBJC_METACLASS_$_";
  Result += CDecl->getNameAsString(); Result += ";\n";
  
  if (!rootClass) {
    Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
    Result += ".superclass = "; Result += "&OBJC_CLASS_$_";
    Result += SuperClass->getNameAsString(); Result += ";\n";
  }
  
  Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
  Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n";
  Result += "}\n";
}

static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, 
                             std::string &Result,
                             ObjCCategoryDecl *CatDecl,
                             ObjCInterfaceDecl *ClassDecl,
                             ArrayRef<ObjCMethodDecl *> InstanceMethods,
                             ArrayRef<ObjCMethodDecl *> ClassMethods,
                             ArrayRef<ObjCProtocolDecl *> RefedProtocols,
                             ArrayRef<ObjCPropertyDecl *> ClassProperties) {
  StringRef CatName = CatDecl->getName();
  StringRef ClassName = ClassDecl->getName();
  // must declare an extern class object in case this class is not implemented 
  // in this TU.
  Result += "\n";
  Result += "extern \"C\" ";
  if (ClassDecl->getImplementation())
    Result += "__declspec(dllexport) ";
  else
    Result += "__declspec(dllimport) ";
  
  Result += "struct _class_t ";
  Result += "OBJC_CLASS_$_"; Result += ClassName;
  Result += ";\n";
  
  Result += "\nstatic struct _category_t ";
  Result += "_OBJC_$_CATEGORY_";
  Result += ClassName; Result += "_$_"; Result += CatName;
  Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
  Result += "{\n";
  Result += "\t\""; Result += ClassName; Result += "\",\n";
  Result += "\t0, // &"; Result += "OBJC_CLASS_$_"; Result += ClassName;
  Result += ",\n";
  if (InstanceMethods.size() > 0) {
    Result += "\t(const struct _method_list_t *)&";  
    Result += "_OBJC_$_CATEGORY_INSTANCE_METHODS_";
    Result += ClassName; Result += "_$_"; Result += CatName;
    Result += ",\n";
  }
  else
    Result += "\t0,\n";
  
  if (ClassMethods.size() > 0) {
    Result += "\t(const struct _method_list_t *)&";  
    Result += "_OBJC_$_CATEGORY_CLASS_METHODS_";
    Result += ClassName; Result += "_$_"; Result += CatName;
    Result += ",\n";
  }
  else
    Result += "\t0,\n";
  
  if (RefedProtocols.size() > 0) {
    Result += "\t(const struct _protocol_list_t *)&";  
    Result += "_OBJC_CATEGORY_PROTOCOLS_$_";
    Result += ClassName; Result += "_$_"; Result += CatName;
    Result += ",\n";
  }
  else
    Result += "\t0,\n";
  
  if (ClassProperties.size() > 0) {
    Result += "\t(const struct _prop_list_t *)&";  Result += "_OBJC_$_PROP_LIST_";
    Result += ClassName; Result += "_$_"; Result += CatName;
    Result += ",\n";
  }
  else
    Result += "\t0,\n";
  
  Result += "};\n";
  
  // Add static function to initialize the class pointer in the category structure.
  Result += "static void OBJC_CATEGORY_SETUP_$_";
  Result += ClassDecl->getNameAsString();
  Result += "_$_";
  Result += CatName;
  Result += "(void ) {\n";
  Result += "\t_OBJC_$_CATEGORY_"; 
  Result += ClassDecl->getNameAsString();
  Result += "_$_";
  Result += CatName;
  Result += ".cls = "; Result += "&OBJC_CLASS_$_"; Result += ClassName;
  Result += ";\n}\n";
}

static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
                                           ASTContext *Context, std::string &Result,
                                           ArrayRef<ObjCMethodDecl *> Methods,
                                           StringRef VarName,
                                           StringRef ProtocolName) {
  if (Methods.size() == 0)
    return;
  
  Result += "\nstatic const char *";
  Result += VarName; Result += ProtocolName;
  Result += " [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
  Result += "{\n";
  for (unsigned i = 0, e = Methods.size(); i < e; i++) {
    ObjCMethodDecl *MD = Methods[i];
    std::string MethodTypeString, QuoteMethodTypeString;
    Context->getObjCEncodingForMethodDecl(MD, MethodTypeString, true);
    RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
    Result += "\t\""; Result += QuoteMethodTypeString; Result += "\"";
    if (i == e-1)
      Result += "\n};\n";
    else {
      Result += ",\n";
    }
  }
}

static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
                                ASTContext *Context,
                                std::string &Result, 
                                ArrayRef<ObjCIvarDecl *> Ivars, 
                                ObjCInterfaceDecl *CDecl) {
  // FIXME. visibilty of offset symbols may have to be set; for Darwin
  // this is what happens:
  /**
   if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
       Ivar->getAccessControl() == ObjCIvarDecl::Package ||
       Class->getVisibility() == HiddenVisibility)
     Visibility shoud be: HiddenVisibility;
   else
     Visibility shoud be: DefaultVisibility;
  */
  
  Result += "\n";
  for (unsigned i =0, e = Ivars.size(); i < e; i++) {
    ObjCIvarDecl *IvarDecl = Ivars[i];
    if (Context->getLangOpts().MicrosoftExt)
      Result += "__declspec(allocate(\".objc_ivar$B\")) ";
    
    if (!Context->getLangOpts().MicrosoftExt ||
        IvarDecl->getAccessControl() == ObjCIvarDecl::Private ||
        IvarDecl->getAccessControl() == ObjCIvarDecl::Package)
      Result += "extern \"C\" unsigned long int "; 
    else
      Result += "extern \"C\" __declspec(dllexport) unsigned long int ";
    WriteInternalIvarName(CDecl, IvarDecl, Result);
    Result += " __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
    Result += " = ";
    RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
    Result += ";\n";
  }
}

static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
                                           ASTContext *Context, std::string &Result,
                                           ArrayRef<ObjCIvarDecl *> Ivars,
                                           StringRef VarName,
                                           ObjCInterfaceDecl *CDecl) {
  if (Ivars.size() > 0) {
    Write_IvarOffsetVar(RewriteObj, Context, Result, Ivars, CDecl);
    
    Result += "\nstatic ";
    Write__ivar_list_t_TypeDecl(Result, Ivars.size());
    Result += " "; Result += VarName;
    Result += CDecl->getNameAsString();
    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
    Result += "\t"; Result += "sizeof(_ivar_t)"; Result += ",\n";
    Result += "\t"; Result += utostr(Ivars.size()); Result += ",\n";
    for (unsigned i =0, e = Ivars.size(); i < e; i++) {
      ObjCIvarDecl *IvarDecl = Ivars[i];
      if (i == 0)
        Result += "\t{{";
      else
        Result += "\t {";
      Result += "(unsigned long int *)&";
      WriteInternalIvarName(CDecl, IvarDecl, Result);
      Result += ", ";
      
      Result += "\""; Result += IvarDecl->getName(); Result += "\", ";
      std::string IvarTypeString, QuoteIvarTypeString;
      Context->getObjCEncodingForType(IvarDecl->getType(), IvarTypeString,
                                      IvarDecl);
      RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
      Result += "\""; Result += QuoteIvarTypeString; Result += "\", ";
      
      // FIXME. this alignment represents the host alignment and need be changed to
      // represent the target alignment.
      unsigned Align = Context->getTypeAlign(IvarDecl->getType())/8;
      Align = llvm::Log2_32(Align);
      Result += llvm::utostr(Align); Result += ", ";
      CharUnits Size = Context->getTypeSizeInChars(IvarDecl->getType());
      Result += llvm::utostr(Size.getQuantity());
      if (i  == e-1)
        Result += "}}\n";
      else
        Result += "},\n";
    }
    Result += "};\n";
  }
}

/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, 
                                                    std::string &Result) {
  
  // Do not synthesize the protocol more than once.
  if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl()))
    return;
  WriteModernMetadataDeclarations(Context, Result);
  
  if (ObjCProtocolDecl *Def = PDecl->getDefinition())
    PDecl = Def;
  // Must write out all protocol definitions in current qualifier list,
  // and in their nested qualifiers before writing out current definition.
  for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(),
       E = PDecl->protocol_end(); I != E; ++I)
    RewriteObjCProtocolMetaData(*I, Result);
  
  // Construct method lists.
  std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
  std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
  for (ObjCProtocolDecl::instmeth_iterator
       I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
       I != E; ++I) {
    ObjCMethodDecl *MD = *I;
    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
      OptInstanceMethods.push_back(MD);
    } else {
      InstanceMethods.push_back(MD);
    }
  }
  
  for (ObjCProtocolDecl::classmeth_iterator
       I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
       I != E; ++I) {
    ObjCMethodDecl *MD = *I;
    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
      OptClassMethods.push_back(MD);
    } else {
      ClassMethods.push_back(MD);
    }
  }
  std::vector<ObjCMethodDecl *> AllMethods;
  for (unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
    AllMethods.push_back(InstanceMethods[i]);
  for (unsigned i = 0, e = ClassMethods.size(); i < e; i++)
    AllMethods.push_back(ClassMethods[i]);
  for (unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
    AllMethods.push_back(OptInstanceMethods[i]);
  for (unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
    AllMethods.push_back(OptClassMethods[i]);

  Write__extendedMethodTypes_initializer(*this, Context, Result,
                                         AllMethods,
                                         "_OBJC_PROTOCOL_METHOD_TYPES_",
                                         PDecl->getNameAsString());
  // Protocol's super protocol list
  std::vector<ObjCProtocolDecl *> SuperProtocols;
  for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(),
       E = PDecl->protocol_end(); I != E; ++I)
    SuperProtocols.push_back(*I);
  
  Write_protocol_list_initializer(Context, Result, SuperProtocols,
                                  "_OBJC_PROTOCOL_REFS_",
                                  PDecl->getNameAsString());
  
  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 
                                  "_OBJC_PROTOCOL_INSTANCE_METHODS_",
                                  PDecl->getNameAsString(), false);
  
  Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 
                                  "_OBJC_PROTOCOL_CLASS_METHODS_",
                                  PDecl->getNameAsString(), false);

  Write_method_list_t_initializer(*this, Context, Result, OptInstanceMethods, 
                                  "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
                                  PDecl->getNameAsString(), false);
  
  Write_method_list_t_initializer(*this, Context, Result, OptClassMethods, 
                                  "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
                                  PDecl->getNameAsString(), false);
  
  // Protocol's property metadata.
  std::vector<ObjCPropertyDecl *> ProtocolProperties;
  for (ObjCContainerDecl::prop_iterator I = PDecl->prop_begin(),
       E = PDecl->prop_end(); I != E; ++I)
    ProtocolProperties.push_back(*I);
  
  Write_prop_list_t_initializer(*this, Context, Result, ProtocolProperties,
                                 /* Container */0,
                                 "_OBJC_PROTOCOL_PROPERTIES_",
                                 PDecl->getNameAsString());
  
  // Writer out root metadata for current protocol: struct _protocol_t
  Result += "\n";
  if (LangOpts.MicrosoftExt)
    Result += "static ";
  Result += "struct _protocol_t _OBJC_PROTOCOL_";
  Result += PDecl->getNameAsString();
  Result += " __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n";
  Result += "\t0,\n"; // id is; is null
  Result += "\t\""; Result += PDecl->getNameAsString(); Result += "\",\n";
  if (SuperProtocols.size() > 0) {
    Result += "\t(const struct _protocol_list_t *)&"; Result += "_OBJC_PROTOCOL_REFS_";
    Result += PDecl->getNameAsString(); Result += ",\n";
  }
  else
    Result += "\t0,\n";
  if (InstanceMethods.size() > 0) {
    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 
    Result += PDecl->getNameAsString(); Result += ",\n";
  }
  else
    Result += "\t0,\n";

  if (ClassMethods.size() > 0) {
    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 
    Result += PDecl->getNameAsString(); Result += ",\n";
  }
  else
    Result += "\t0,\n";
  
  if (OptInstanceMethods.size() > 0) {
    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_"; 
    Result += PDecl->getNameAsString(); Result += ",\n";
  }
  else
    Result += "\t0,\n";
  
  if (OptClassMethods.size() > 0) {
    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_"; 
    Result += PDecl->getNameAsString(); Result += ",\n";
  }
  else
    Result += "\t0,\n";
  
  if (ProtocolProperties.size() > 0) {
    Result += "\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_"; 
    Result += PDecl->getNameAsString(); Result += ",\n";
  }
  else
    Result += "\t0,\n";
  
  Result += "\t"; Result += "sizeof(_protocol_t)"; Result += ",\n";
  Result += "\t0,\n";
  
  if (AllMethods.size() > 0) {
    Result += "\t(const char **)&"; Result += "_OBJC_PROTOCOL_METHOD_TYPES_";
    Result += PDecl->getNameAsString();
    Result += "\n};\n";
  }
  else
    Result += "\t0\n};\n";
  
  if (LangOpts.MicrosoftExt)
    Result += "static ";
  Result += "struct _protocol_t *";
  Result += "_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->getNameAsString();
  Result += " = &_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
  Result += ";\n";
    
  // Mark this protocol as having been generated.
  if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()))
    llvm_unreachable("protocol already synthesized");
  
}

void RewriteModernObjC::RewriteObjCProtocolListMetaData(
                                const ObjCList<ObjCProtocolDecl> &Protocols,
                                StringRef prefix, StringRef ClassName,
                                std::string &Result) {
  if (Protocols.empty()) return;
  
  for (unsigned i = 0; i != Protocols.size(); i++)
    RewriteObjCProtocolMetaData(Protocols[i], 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 += "\n";
  if (LangOpts.MicrosoftExt)
    Result += "__declspec(allocate(\".cat_cls_meth$B\")) ";
  Result += "static 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";
}

/// hasObjCExceptionAttribute - Return true if this class or any super
/// class has the __objc_exception__ attribute.
/// FIXME. Move this to ASTContext.cpp as it is also used for IRGen.
static bool hasObjCExceptionAttribute(ASTContext &Context,
                                      const ObjCInterfaceDecl *OID) {
  if (OID->hasAttr<ObjCExceptionAttr>())
    return true;
  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
    return hasObjCExceptionAttribute(Context, Super);
  return false;
}

void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
                                           std::string &Result) {
  ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
  
  // Explicitly declared @interface's are already synthesized.
  if (CDecl->isImplicitInterfaceDecl())
    assert(false && 
           "Legacy implicit interface rewriting not supported in moder abi");
  
  WriteModernMetadataDeclarations(Context, Result);
  SmallVector<ObjCIvarDecl *, 8> IVars;
  
  for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
      IVD; IVD = IVD->getNextIvar()) {
    // Ignore unnamed bit-fields.
    if (!IVD->getDeclName())
      continue;
    IVars.push_back(IVD);
  }
  
  Write__ivar_list_t_initializer(*this, Context, Result, IVars, 
                                 "_OBJC_$_INSTANCE_VARIABLES_",
                                 CDecl);
  
  // Build _objc_method_list for class's instance methods if needed
  SmallVector<ObjCMethodDecl *, 32>
    InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
  
  // 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(),
       PropEnd = IDecl->propimpl_end();
       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())
      if (mustSynthesizeSetterGetterMethod(IDecl, PD, true /*getter*/))
        InstanceMethods.push_back(Getter);
    if (PD->isReadOnly())
      continue;
    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
      if (mustSynthesizeSetterGetterMethod(IDecl, PD, false /*setter*/))
        InstanceMethods.push_back(Setter);
  }
  
  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
                                  "_OBJC_$_INSTANCE_METHODS_",
                                  IDecl->getNameAsString(), true);
  
  SmallVector<ObjCMethodDecl *, 32>
    ClassMethods(IDecl->classmeth_begin(), IDecl->classmeth_end());
  
  Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
                                  "_OBJC_$_CLASS_METHODS_",
                                  IDecl->getNameAsString(), true);
  
  // Protocols referenced in class declaration?
  // Protocol's super protocol list
  std::vector<ObjCProtocolDecl *> RefedProtocols;
  const ObjCList<ObjCProtocolDecl> &Protocols = CDecl->getReferencedProtocols();
  for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
       E = Protocols.end();
       I != E; ++I) {
    RefedProtocols.push_back(*I);
    // Must write out all protocol definitions in current qualifier list,
    // and in their nested qualifiers before writing out current definition.
    RewriteObjCProtocolMetaData(*I, Result);
  }
  
  Write_protocol_list_initializer(Context, Result, 
                                  RefedProtocols,
                                  "_OBJC_CLASS_PROTOCOLS_$_",
                                  IDecl->getNameAsString());
  
  // Protocol's property metadata.
  std::vector<ObjCPropertyDecl *> ClassProperties;
  for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
       E = CDecl->prop_end(); I != E; ++I)
    ClassProperties.push_back(*I);
  
  Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
                                 /* Container */IDecl,
                                 "_OBJC_$_PROP_LIST_",
                                 CDecl->getNameAsString());

  
  // Data for initializing _class_ro_t  metaclass meta-data
  uint32_t flags = CLS_META;
  std::string InstanceSize;
  std::string InstanceStart;
  
  
  bool classIsHidden = CDecl->getVisibility() == HiddenVisibility;
  if (classIsHidden)
    flags |= OBJC2_CLS_HIDDEN;
  
  if (!CDecl->getSuperClass())
    // class is root
    flags |= CLS_ROOT;
  InstanceSize = "sizeof(struct _class_t)";
  InstanceStart = InstanceSize;
  Write__class_ro_t_initializer(Context, Result, flags, 
                                InstanceStart, InstanceSize,
                                ClassMethods,
                                0,
                                0,
                                0,
                                "_OBJC_METACLASS_RO_$_",
                                CDecl->getNameAsString());

  
  // Data for initializing _class_ro_t meta-data
  flags = CLS;
  if (classIsHidden)
    flags |= OBJC2_CLS_HIDDEN;
  
  if (hasObjCExceptionAttribute(*Context, CDecl))
    flags |= CLS_EXCEPTION;

  if (!CDecl->getSuperClass())
    // class is root
    flags |= CLS_ROOT;
  
  InstanceSize.clear();
  InstanceStart.clear();
  if (!ObjCSynthesizedStructs.count(CDecl)) {
    InstanceSize = "0";
    InstanceStart = "0";
  }
  else {
    InstanceSize = "sizeof(struct ";
    InstanceSize += CDecl->getNameAsString();
    InstanceSize += "_IMPL)";
    
    ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
    if (IVD) {
      RewriteIvarOffsetComputation(IVD, InstanceStart);
    }
    else 
      InstanceStart = InstanceSize;
  }
  Write__class_ro_t_initializer(Context, Result, flags, 
                                InstanceStart, InstanceSize,
                                InstanceMethods,
                                RefedProtocols,
                                IVars,
                                ClassProperties,
                                "_OBJC_CLASS_RO_$_",
                                CDecl->getNameAsString());
  
  Write_class_t(Context, Result,
                "OBJC_METACLASS_$_",
                CDecl, /*metaclass*/true);
  
  Write_class_t(Context, Result,
                "OBJC_CLASS_$_",
                CDecl, /*metaclass*/false);
  
  if (ImplementationIsNonLazy(IDecl))
    DefinedNonLazyClasses.push_back(CDecl);
                
}

void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
  int ClsDefCount = ClassImplementation.size();
  if (!ClsDefCount)
    return;
  Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n";
  Result += "__declspec(allocate(\".objc_inithooks$B\")) ";
  Result += "static void *OBJC_CLASS_SETUP[] = {\n";
  for (int i = 0; i < ClsDefCount; i++) {
    ObjCImplementationDecl *IDecl = ClassImplementation[i];
    ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
    Result += "\t(void *)&OBJC_CLASS_SETUP_$_";
    Result  += CDecl->getName(); Result += ",\n";
  }
  Result += "};\n";
}

void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
  int ClsDefCount = ClassImplementation.size();
  int CatDefCount = CategoryImplementation.size();
  
  // For each implemented class, write out all its meta data.
  for (int i = 0; i < ClsDefCount; i++)
    RewriteObjCClassMetaData(ClassImplementation[i], Result);
  
  RewriteClassSetupInitHook(Result);
  
  // For each implemented category, write out all its meta data.
  for (int i = 0; i < CatDefCount; i++)
    RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
  
  RewriteCategorySetupInitHook(Result);
  
  if (ClsDefCount > 0) {
    if (LangOpts.MicrosoftExt)
      Result += "__declspec(allocate(\".objc_classlist$B\")) ";
    Result += "static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
    Result += llvm::utostr(ClsDefCount); Result += "]";
    Result += 
      " __attribute__((used, section (\"__DATA, __objc_classlist,"
      "regular,no_dead_strip\")))= {\n";
    for (int i = 0; i < ClsDefCount; i++) {
      Result += "\t&OBJC_CLASS_$_";
      Result += ClassImplementation[i]->getNameAsString();
      Result += ",\n";
    }
    Result += "};\n";
    
    if (!DefinedNonLazyClasses.empty()) {
      if (LangOpts.MicrosoftExt)
        Result += "__declspec(allocate(\".objc_nlclslist$B\")) \n";
      Result += "static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
      for (unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
        Result += "\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
        Result += ",\n";
      }
      Result += "};\n";
    }
  }
  
  if (CatDefCount > 0) {
    if (LangOpts.MicrosoftExt)
      Result += "__declspec(allocate(\".objc_catlist$B\")) ";
    Result += "static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
    Result += llvm::utostr(CatDefCount); Result += "]";
    Result += 
    " __attribute__((used, section (\"__DATA, __objc_catlist,"
    "regular,no_dead_strip\")))= {\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";
  }
  
  if (!DefinedNonLazyCategories.empty()) {
    if (LangOpts.MicrosoftExt)
      Result += "__declspec(allocate(\".objc_nlcatlist$B\")) \n";
    Result += "static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
    for (unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
      Result += "\t&_OBJC_$_CATEGORY_";
      Result += 
        DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString(); 
      Result += "_$_";
      Result += DefinedNonLazyCategories[i]->getNameAsString();
      Result += ",\n";
    }
    Result += "};\n";
  }
}

void RewriteModernObjC::WriteImageInfo(std::string &Result) {
  if (LangOpts.MicrosoftExt)
    Result += "__declspec(allocate(\".objc_imageinfo$B\")) \n";
  
  Result += "static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
  // version 0, ObjCABI is 2
  Result += "_OBJC_IMAGE_INFO = { 0, 2 };\n";
}

/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
/// implementation.
void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
                                              std::string &Result) {
  WriteModernMetadataDeclarations(Context, Result);
  ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
  // Find category declaration for this implementation.
  ObjCCategoryDecl *CDecl=0;
  for (CDecl = ClassDecl->getCategoryList(); CDecl;
       CDecl = CDecl->getNextClassCategory())
    if (CDecl->getIdentifier() == IDecl->getIdentifier())
      break;
  
  std::string FullCategoryName = ClassDecl->getNameAsString();
  FullCategoryName += "_$_";
  FullCategoryName += CDecl->getNameAsString();
  
  // Build _objc_method_list for class's instance methods if needed
  SmallVector<ObjCMethodDecl *, 32>
  InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
  
  // 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(),
       PropEnd = IDecl->propimpl_end();
       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);
  }
  
  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
                                  "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
                                  FullCategoryName, true);
  
  SmallVector<ObjCMethodDecl *, 32>
    ClassMethods(IDecl->classmeth_begin(), IDecl->classmeth_end());
  
  Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
                                  "_OBJC_$_CATEGORY_CLASS_METHODS_",
                                  FullCategoryName, true);
  
  // Protocols referenced in class declaration?
  // Protocol's super protocol list
  std::vector<ObjCProtocolDecl *> RefedProtocols;
  for (ObjCInterfaceDecl::protocol_iterator I = CDecl->protocol_begin(),
                                            E = CDecl->protocol_end();

         I != E; ++I) {
    RefedProtocols.push_back(*I);
    // Must write out all protocol definitions in current qualifier list,
    // and in their nested qualifiers before writing out current definition.
    RewriteObjCProtocolMetaData(*I, Result);
  }
  
  Write_protocol_list_initializer(Context, Result, 
                                  RefedProtocols,
                                  "_OBJC_CATEGORY_PROTOCOLS_$_",
                                  FullCategoryName);
  
  // Protocol's property metadata.
  std::vector<ObjCPropertyDecl *> ClassProperties;
  for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
       E = CDecl->prop_end(); I != E; ++I)
    ClassProperties.push_back(*I);
  
  Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
                                /* Container */IDecl,
                                "_OBJC_$_PROP_LIST_",
                                FullCategoryName);
  
  Write_category_t(*this, Context, Result,
                   CDecl,
                   ClassDecl,
                   InstanceMethods,
                   ClassMethods,
                   RefedProtocols,
                   ClassProperties);
  
  // Determine if this category is also "non-lazy".
  if (ImplementationIsNonLazy(IDecl))
    DefinedNonLazyCategories.push_back(CDecl);
    
}

void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
  int CatDefCount = CategoryImplementation.size();
  if (!CatDefCount)
    return;
  Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n";
  Result += "__declspec(allocate(\".objc_inithooks$B\")) ";
  Result += "static void *OBJC_CATEGORY_SETUP[] = {\n";
  for (int i = 0; i < CatDefCount; i++) {
    ObjCCategoryImplDecl *IDecl = CategoryImplementation[i];
    ObjCCategoryDecl *CatDecl= IDecl->getCategoryDecl();
    ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
    Result += "\t(void *)&OBJC_CATEGORY_SETUP_$_";
    Result += ClassDecl->getName();
    Result += "_$_";
    Result += CatDecl->getName();
    Result += ",\n";
  }
  Result += "};\n";
}

// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
/// class methods.
template<typename MethodIterator>
void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
                                             MethodIterator MethodEnd,
                                             bool IsInstanceMethod,
                                             StringRef prefix,
                                             StringRef ClassName,
                                             std::string &Result) {
  if (MethodBegin == MethodEnd) return;
  
  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 += "\n";
  if (LangOpts.MicrosoftExt) {
    if (IsInstanceMethod)
      Result += "__declspec(allocate(\".inst_meth$B\")) ";
    else
      Result += "__declspec(allocate(\".cls_meth$B\")) ";
  }
  Result += "static 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";
}

Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
  SourceRange OldRange = IV->getSourceRange();
  Expr *BaseExpr = IV->getBase();
  
  // Rewrite the base, but without actually doing replaces.
  {
    DisableReplaceStmtScope S(*this);
    BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
    IV->setBase(BaseExpr);
  }
  
  ObjCIvarDecl *D = IV->getDecl();
  
  Expr *Replacement = IV;
  
    if (BaseExpr->getType()->isObjCObjectPointerType()) {
      const ObjCInterfaceType *iFaceDecl =
        dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
      assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
      // lookup which class implements the instance variable.
      ObjCInterfaceDecl *clsDeclared = 0;
      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
                                                   clsDeclared);
      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
      
      // Build name of symbol holding ivar offset.
      std::string IvarOffsetName;
      WriteInternalIvarName(clsDeclared, D, IvarOffsetName);
      
      ReferencedIvars[clsDeclared].insert(D);
      
      // cast offset to "char *".
      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, 
                                                    Context->getPointerType(Context->CharTy),
                                                    CK_BitCast,
                                                    BaseExpr);
      VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
                                       SourceLocation(), &Context->Idents.get(IvarOffsetName),
                                       Context->UnsignedLongTy, 0, SC_Extern, SC_None);
      DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false,
                                                   Context->UnsignedLongTy, VK_LValue,
                                                   SourceLocation());
      BinaryOperator *addExpr = 
        new (Context) BinaryOperator(castExpr, DRE, BO_Add, 
                                     Context->getPointerType(Context->CharTy),
                                     VK_RValue, OK_Ordinary, SourceLocation(), false);
      // Don't forget the parens to enforce the proper binding.
      ParenExpr *PE = new (Context) ParenExpr(SourceLocation(),
                                              SourceLocation(),
                                              addExpr);
      QualType IvarT = D->getType();

      if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
        RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
        RD = RD->getDefinition();
        if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
          // decltype(((Foo_IMPL*)0)->bar) *
          ObjCContainerDecl *CDecl = 
            dyn_cast<ObjCContainerDecl>(D->getDeclContext());
          // ivar in class extensions requires special treatment.
          if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
            CDecl = CatDecl->getClassInterface();
          std::string RecName = CDecl->getName();
          RecName += "_IMPL";
          RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
                                              SourceLocation(), SourceLocation(),
                                              &Context->Idents.get(RecName.c_str()));
          QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
          unsigned UnsignedIntSize = 
            static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
          Expr *Zero = IntegerLiteral::Create(*Context,
                                              llvm::APInt(UnsignedIntSize, 0),
                                              Context->UnsignedIntTy, SourceLocation());
          Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
          ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
                                                  Zero);
          FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
                                            SourceLocation(),
                                            &Context->Idents.get(D->getNameAsString()),
                                            IvarT, 0,
                                            /*BitWidth=*/0, /*Mutable=*/true,
                                            ICIS_NoInit);
          MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
                                                    FD->getType(), VK_LValue,
                                                    OK_Ordinary);
          IvarT = Context->getDecltypeType(ME, ME->getType());
        }
      }
      convertObjCTypeToCStyleType(IvarT);
      QualType castT = Context->getPointerType(IvarT);
          
      castExpr = NoTypeInfoCStyleCastExpr(Context, 
                                          castT,
                                          CK_BitCast,
                                          PE);
      
      
      Expr *Exp = new (Context) UnaryOperator(castExpr, UO_Deref, IvarT,
                                              VK_LValue, OK_Ordinary,
                                              SourceLocation());
      PE = new (Context) ParenExpr(OldRange.getBegin(),
                                   OldRange.getEnd(),
                                   Exp);

      Replacement = PE;
    }
  
    ReplaceStmtWithRange(IV, Replacement, OldRange);
    return Replacement;  
}
