]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Rewrite/RewriteObjC.cpp
Merge ACPICA 20100806.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Rewrite / RewriteObjC.cpp
1 //===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Hacks and fun related to the code rewriter.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/Rewrite/ASTConsumers.h"
15 #include "clang/Rewrite/Rewriter.h"
16 #include "clang/AST/AST.h"
17 #include "clang/AST/ASTConsumer.h"
18 #include "clang/AST/ParentMap.h"
19 #include "clang/Basic/SourceManager.h"
20 #include "clang/Basic/IdentifierTable.h"
21 #include "clang/Basic/Diagnostic.h"
22 #include "clang/Lex/Lexer.h"
23 #include "llvm/Support/MemoryBuffer.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/ADT/StringExtras.h"
26 #include "llvm/ADT/SmallPtrSet.h"
27 #include "llvm/ADT/OwningPtr.h"
28 #include "llvm/ADT/DenseSet.h"
29
30 using namespace clang;
31 using llvm::utostr;
32
33 namespace {
34   class RewriteObjC : public ASTConsumer {
35     enum {
36       BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)), 
37                                         block, ... */
38       BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
39       BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the 
40                                         __block variable */
41       BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy 
42                                         helpers */
43       BLOCK_BYREF_CALLER      = 128, /* called from __block (byref) copy/dispose 
44                                         support routines */
45       BLOCK_BYREF_CURRENT_MAX = 256
46     };
47     
48     enum {
49       BLOCK_NEEDS_FREE =        (1 << 24),
50       BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
51       BLOCK_HAS_CXX_OBJ =       (1 << 26),
52       BLOCK_IS_GC =             (1 << 27),
53       BLOCK_IS_GLOBAL =         (1 << 28),
54       BLOCK_HAS_DESCRIPTOR =    (1 << 29)
55     };
56     
57     Rewriter Rewrite;
58     Diagnostic &Diags;
59     const LangOptions &LangOpts;
60     unsigned RewriteFailedDiag;
61     unsigned TryFinallyContainsReturnDiag;
62
63     ASTContext *Context;
64     SourceManager *SM;
65     TranslationUnitDecl *TUDecl;
66     FileID MainFileID;
67     const char *MainFileStart, *MainFileEnd;
68     SourceLocation LastIncLoc;
69
70     llvm::SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
71     llvm::SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
72     llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
73     llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
74     llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls;
75     llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
76     llvm::SmallVector<Stmt *, 32> Stmts;
77     llvm::SmallVector<int, 8> ObjCBcLabelNo;
78     // Remember all the @protocol(<expr>) expressions.
79     llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
80     
81     llvm::DenseSet<uint64_t> CopyDestroyCache;
82     
83     unsigned NumObjCStringLiterals;
84
85     FunctionDecl *MsgSendFunctionDecl;
86     FunctionDecl *MsgSendSuperFunctionDecl;
87     FunctionDecl *MsgSendStretFunctionDecl;
88     FunctionDecl *MsgSendSuperStretFunctionDecl;
89     FunctionDecl *MsgSendFpretFunctionDecl;
90     FunctionDecl *GetClassFunctionDecl;
91     FunctionDecl *GetMetaClassFunctionDecl;
92     FunctionDecl *GetSuperClassFunctionDecl;
93     FunctionDecl *SelGetUidFunctionDecl;
94     FunctionDecl *CFStringFunctionDecl;
95     FunctionDecl *SuperContructorFunctionDecl;
96
97     // ObjC string constant support.
98     VarDecl *ConstantStringClassReference;
99     RecordDecl *NSStringRecord;
100
101     // ObjC foreach break/continue generation support.
102     int BcLabelCount;
103
104     // Needed for super.
105     ObjCMethodDecl *CurMethodDef;
106     RecordDecl *SuperStructDecl;
107     RecordDecl *ConstantStringDecl;
108
109     TypeDecl *ProtocolTypeDecl;
110     QualType getProtocolType();
111
112     // Needed for header files being rewritten
113     bool IsHeader;
114
115     std::string InFileName;
116     llvm::raw_ostream* OutFile;
117
118     bool SilenceRewriteMacroWarning;
119     bool objc_impl_method;
120
121     std::string Preamble;
122
123     // Block expressions.
124     llvm::SmallVector<BlockExpr *, 32> Blocks;
125     llvm::SmallVector<int, 32> InnerDeclRefsCount;
126     llvm::SmallVector<BlockDeclRefExpr *, 32> InnerDeclRefs;
127     
128     llvm::SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs;
129
130     // Block related declarations.
131     llvm::SmallVector<ValueDecl *, 8> BlockByCopyDecls;
132     llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
133     llvm::SmallVector<ValueDecl *, 8> BlockByRefDecls;
134     llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
135     llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
136     llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
137     llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
138     
139     llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
140
141     // This maps a property to it's assignment statement.
142     llvm::DenseMap<ObjCPropertyRefExpr *, BinaryOperator *> PropSetters;
143     // This maps a property to it's synthesied message expression.
144     // This allows us to rewrite chained getters (e.g. o.a.b.c).
145     llvm::DenseMap<ObjCPropertyRefExpr *, Stmt *> PropGetters;
146
147     // This maps an original source AST to it's rewritten form. This allows
148     // us to avoid rewriting the same node twice (which is very uncommon).
149     // This is needed to support some of the exotic property rewriting.
150     llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
151
152     FunctionDecl *CurFunctionDef;
153     FunctionDecl *CurFunctionDeclToDeclareForBlock;
154     VarDecl *GlobalVarDecl;
155
156     bool DisableReplaceStmt;
157
158     static const int OBJC_ABI_VERSION =7 ;
159   public:
160     virtual void Initialize(ASTContext &context);
161
162     // Top Level Driver code.
163     virtual void HandleTopLevelDecl(DeclGroupRef D) {
164       for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
165         HandleTopLevelSingleDecl(*I);
166     }
167     void HandleTopLevelSingleDecl(Decl *D);
168     void HandleDeclInMainFile(Decl *D);
169     RewriteObjC(std::string inFile, llvm::raw_ostream *OS,
170                 Diagnostic &D, const LangOptions &LOpts,
171                 bool silenceMacroWarn);
172
173     ~RewriteObjC() {}
174
175     virtual void HandleTranslationUnit(ASTContext &C);
176
177     void ReplaceStmt(Stmt *Old, Stmt *New) {
178       Stmt *ReplacingStmt = ReplacedNodes[Old];
179
180       if (ReplacingStmt)
181         return; // We can't rewrite the same node twice.
182
183       if (DisableReplaceStmt)
184         return; // Used when rewriting the assignment of a property setter.
185
186       // If replacement succeeded or warning disabled return with no warning.
187       if (!Rewrite.ReplaceStmt(Old, New)) {
188         ReplacedNodes[Old] = New;
189         return;
190       }
191       if (SilenceRewriteMacroWarning)
192         return;
193       Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
194                    << Old->getSourceRange();
195     }
196
197     void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
198       // Measaure the old text.
199       int Size = Rewrite.getRangeSize(SrcRange);
200       if (Size == -1) {
201         Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
202                      << Old->getSourceRange();
203         return;
204       }
205       // Get the new text.
206       std::string SStr;
207       llvm::raw_string_ostream S(SStr);
208       New->printPretty(S, *Context, 0, PrintingPolicy(LangOpts));
209       const std::string &Str = S.str();
210
211       // If replacement succeeded or warning disabled return with no warning.
212       if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
213         ReplacedNodes[Old] = New;
214         return;
215       }
216       if (SilenceRewriteMacroWarning)
217         return;
218       Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
219                    << Old->getSourceRange();
220     }
221
222     void InsertText(SourceLocation Loc, llvm::StringRef Str,
223                     bool InsertAfter = true) {
224       // If insertion succeeded or warning disabled return with no warning.
225       if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
226           SilenceRewriteMacroWarning)
227         return;
228
229       Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
230     }
231
232     void RemoveText(SourceLocation Loc, unsigned StrLen) {
233       // If removal succeeded or warning disabled return with no warning.
234       if (!Rewrite.RemoveText(Loc, StrLen) || SilenceRewriteMacroWarning)
235         return;
236
237       Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
238     }
239
240     void ReplaceText(SourceLocation Start, unsigned OrigLength,
241                      llvm::StringRef Str) {
242       // If removal succeeded or warning disabled return with no warning.
243       if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
244           SilenceRewriteMacroWarning)
245         return;
246
247       Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
248     }
249
250     // Syntactic Rewriting.
251     void RewritePrologue(SourceLocation Loc);
252     void RewriteInclude();
253     void RewriteTabs();
254     void RewriteForwardClassDecl(ObjCClassDecl *Dcl);
255     void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
256                                  ObjCImplementationDecl *IMD,
257                                  ObjCCategoryImplDecl *CID);
258     void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
259     void RewriteImplementationDecl(Decl *Dcl);
260     void RewriteObjCMethodDecl(ObjCMethodDecl *MDecl, std::string &ResultStr);
261     void RewriteTypeIntoString(QualType T, std::string &ResultStr,
262                                const FunctionType *&FPRetType);
263     void RewriteByRefString(std::string &ResultStr, const std::string &Name,
264                             ValueDecl *VD);
265     void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
266     void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
267     void RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *Dcl);
268     void RewriteMethodDeclaration(ObjCMethodDecl *Method);
269     void RewriteProperty(ObjCPropertyDecl *prop);
270     void RewriteFunctionDecl(FunctionDecl *FD);
271     void RewriteBlockPointerType(std::string& Str, QualType Type);
272     void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
273     void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
274     void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
275     void RewriteTypeOfDecl(VarDecl *VD);
276     void RewriteObjCQualifiedInterfaceTypes(Expr *E);
277     bool needToScanForQualifiers(QualType T);
278     bool isSuperReceiver(Expr *recExpr);
279     QualType getSuperStructType();
280     QualType getConstantStringStructType();
281     QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
282     bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
283
284     // Expression Rewriting.
285     Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
286     void CollectPropertySetters(Stmt *S);
287
288     Stmt *CurrentBody;
289     ParentMap *PropParentMap; // created lazily.
290
291     Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
292     Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation OrigStart,
293                                  bool &replaced);
294     Stmt *RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced);
295     Stmt *RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr);
296     Stmt *RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
297                                 SourceRange SrcRange);
298     Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
299     Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
300     Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
301     Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
302     void WarnAboutReturnGotoStmts(Stmt *S);
303     void HasReturnStmts(Stmt *S, bool &hasReturns);
304     void RewriteTryReturnStmts(Stmt *S);
305     void RewriteSyncReturnStmts(Stmt *S, std::string buf);
306     Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
307     Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
308     Stmt *RewriteObjCCatchStmt(ObjCAtCatchStmt *S);
309     Stmt *RewriteObjCFinallyStmt(ObjCAtFinallyStmt *S);
310     Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
311     Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
312                                        SourceLocation OrigEnd);
313     CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
314                                       Expr **args, unsigned nargs,
315                                       SourceLocation StartLoc=SourceLocation(),
316                                       SourceLocation EndLoc=SourceLocation());
317     Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
318                            SourceLocation StartLoc=SourceLocation(),
319                            SourceLocation EndLoc=SourceLocation());
320     Stmt *RewriteBreakStmt(BreakStmt *S);
321     Stmt *RewriteContinueStmt(ContinueStmt *S);
322     void SynthCountByEnumWithState(std::string &buf);
323
324     void SynthMsgSendFunctionDecl();
325     void SynthMsgSendSuperFunctionDecl();
326     void SynthMsgSendStretFunctionDecl();
327     void SynthMsgSendFpretFunctionDecl();
328     void SynthMsgSendSuperStretFunctionDecl();
329     void SynthGetClassFunctionDecl();
330     void SynthGetMetaClassFunctionDecl();
331     void SynthGetSuperClassFunctionDecl();
332     void SynthSelGetUidFunctionDecl();
333     void SynthSuperContructorFunctionDecl();
334
335     // Metadata emission.
336     void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
337                                   std::string &Result);
338
339     void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
340                                      std::string &Result);
341
342     template<typename MethodIterator>
343     void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
344                                     MethodIterator MethodEnd,
345                                     bool IsInstanceMethod,
346                                     const char *prefix,
347                                     const char *ClassName,
348                                     std::string &Result);
349
350     void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
351                                      const char *prefix,
352                                      const char *ClassName,
353                                      std::string &Result);
354     void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots,
355                                          const char *prefix,
356                                          const char *ClassName,
357                                          std::string &Result);
358     void SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
359                                       std::string &Result);
360     void SynthesizeIvarOffsetComputation(ObjCContainerDecl *IDecl,
361                                          ObjCIvarDecl *ivar,
362                                          std::string &Result);
363     void RewriteImplementations();
364     void SynthesizeMetaDataIntoBuffer(std::string &Result);
365
366     // Block rewriting.
367     void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
368     void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
369
370     void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
371     void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
372
373     // Block specific rewrite rules.
374     void RewriteBlockCall(CallExpr *Exp);
375     void RewriteBlockPointerDecl(NamedDecl *VD);
376     void RewriteByRefVar(VarDecl *VD);
377     std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag);
378     Stmt *RewriteBlockDeclRefExpr(Expr *VD);
379     Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
380     void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
381
382     std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
383                                       const char *funcName, std::string Tag);
384     std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
385                                       const char *funcName, std::string Tag);
386     std::string SynthesizeBlockImpl(BlockExpr *CE, 
387                                     std::string Tag, std::string Desc);
388     std::string SynthesizeBlockDescriptor(std::string DescTag, 
389                                           std::string ImplTag,
390                                           int i, const char *funcName,
391                                           unsigned hasCopy);
392     Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
393     void SynthesizeBlockLiterals(SourceLocation FunLocStart,
394                                  const char *FunName);
395     void RewriteRecordBody(RecordDecl *RD);
396
397     void CollectBlockDeclRefInfo(BlockExpr *Exp);
398     void GetBlockDeclRefExprs(Stmt *S);
399     void GetInnerBlockDeclRefExprs(Stmt *S, 
400                 llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
401                 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
402
403     // We avoid calling Type::isBlockPointerType(), since it operates on the
404     // canonical type. We only care if the top-level type is a closure pointer.
405     bool isTopLevelBlockPointerType(QualType T) {
406       return isa<BlockPointerType>(T);
407     }
408
409     /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
410     /// to a function pointer type and upon success, returns true; false
411     /// otherwise.
412     bool convertBlockPointerToFunctionPointer(QualType &T) {
413       if (isTopLevelBlockPointerType(T)) {
414         const BlockPointerType *BPT = T->getAs<BlockPointerType>();
415         T = Context->getPointerType(BPT->getPointeeType());
416         return true;
417       }
418       return false;
419     }
420     
421     // FIXME: This predicate seems like it would be useful to add to ASTContext.
422     bool isObjCType(QualType T) {
423       if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
424         return false;
425
426       QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
427
428       if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
429           OCT == Context->getCanonicalType(Context->getObjCClassType()))
430         return true;
431
432       if (const PointerType *PT = OCT->getAs<PointerType>()) {
433         if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
434             PT->getPointeeType()->isObjCQualifiedIdType())
435           return true;
436       }
437       return false;
438     }
439     bool PointerTypeTakesAnyBlockArguments(QualType QT);
440     void GetExtentOfArgList(const char *Name, const char *&LParen,
441                             const char *&RParen);
442     void RewriteCastExpr(CStyleCastExpr *CE);
443
444     FunctionDecl *SynthBlockInitFunctionDecl(const char *name);
445     Stmt *SynthBlockInitExpr(BlockExpr *Exp,
446             const llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs);
447
448     void QuoteDoublequotes(std::string &From, std::string &To) {
449       for (unsigned i = 0; i < From.length(); i++) {
450         if (From[i] == '"')
451           To += "\\\"";
452         else
453           To += From[i];
454       }
455     }
456   };
457
458   // Helper function: create a CStyleCastExpr with trivial type source info.
459   CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
460                                            CastExpr::CastKind Kind, Expr *E) {
461     TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
462     return new (Ctx) CStyleCastExpr(Ty, Kind, E, CXXBaseSpecifierArray(), TInfo,
463                                     SourceLocation(), SourceLocation());
464   }
465 }
466
467 void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
468                                                    NamedDecl *D) {
469   if (FunctionProtoType *fproto = dyn_cast<FunctionProtoType>(funcType)) {
470     for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(),
471          E = fproto->arg_type_end(); I && (I != E); ++I)
472       if (isTopLevelBlockPointerType(*I)) {
473         // All the args are checked/rewritten. Don't call twice!
474         RewriteBlockPointerDecl(D);
475         break;
476       }
477   }
478 }
479
480 void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
481   const PointerType *PT = funcType->getAs<PointerType>();
482   if (PT && PointerTypeTakesAnyBlockArguments(funcType))
483     RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
484 }
485
486 static bool IsHeaderFile(const std::string &Filename) {
487   std::string::size_type DotPos = Filename.rfind('.');
488
489   if (DotPos == std::string::npos) {
490     // no file extension
491     return false;
492   }
493
494   std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
495   // C header: .h
496   // C++ header: .hh or .H;
497   return Ext == "h" || Ext == "hh" || Ext == "H";
498 }
499
500 RewriteObjC::RewriteObjC(std::string inFile, llvm::raw_ostream* OS,
501                          Diagnostic &D, const LangOptions &LOpts,
502                          bool silenceMacroWarn)
503       : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
504         SilenceRewriteMacroWarning(silenceMacroWarn) {
505   IsHeader = IsHeaderFile(inFile);
506   RewriteFailedDiag = Diags.getCustomDiagID(Diagnostic::Warning,
507                "rewriting sub-expression within a macro (may not be correct)");
508   TryFinallyContainsReturnDiag = Diags.getCustomDiagID(Diagnostic::Warning,
509                "rewriter doesn't support user-specified control flow semantics "
510                "for @try/@finally (code may not execute properly)");
511 }
512
513 ASTConsumer *clang::CreateObjCRewriter(const std::string& InFile,
514                                        llvm::raw_ostream* OS,
515                                        Diagnostic &Diags,
516                                        const LangOptions &LOpts,
517                                        bool SilenceRewriteMacroWarning) {
518   return new RewriteObjC(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning);
519 }
520
521 void RewriteObjC::Initialize(ASTContext &context) {
522   Context = &context;
523   SM = &Context->getSourceManager();
524   TUDecl = Context->getTranslationUnitDecl();
525   MsgSendFunctionDecl = 0;
526   MsgSendSuperFunctionDecl = 0;
527   MsgSendStretFunctionDecl = 0;
528   MsgSendSuperStretFunctionDecl = 0;
529   MsgSendFpretFunctionDecl = 0;
530   GetClassFunctionDecl = 0;
531   GetMetaClassFunctionDecl = 0;
532   GetSuperClassFunctionDecl = 0;
533   SelGetUidFunctionDecl = 0;
534   CFStringFunctionDecl = 0;
535   ConstantStringClassReference = 0;
536   NSStringRecord = 0;
537   CurMethodDef = 0;
538   CurFunctionDef = 0;
539   CurFunctionDeclToDeclareForBlock = 0;
540   GlobalVarDecl = 0;
541   SuperStructDecl = 0;
542   ProtocolTypeDecl = 0;
543   ConstantStringDecl = 0;
544   BcLabelCount = 0;
545   SuperContructorFunctionDecl = 0;
546   NumObjCStringLiterals = 0;
547   PropParentMap = 0;
548   CurrentBody = 0;
549   DisableReplaceStmt = false;
550   objc_impl_method = false;
551
552   // Get the ID and start/end of the main file.
553   MainFileID = SM->getMainFileID();
554   const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
555   MainFileStart = MainBuf->getBufferStart();
556   MainFileEnd = MainBuf->getBufferEnd();
557
558   Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOptions());
559
560   // declaring objc_selector outside the parameter list removes a silly
561   // scope related warning...
562   if (IsHeader)
563     Preamble = "#pragma once\n";
564   Preamble += "struct objc_selector; struct objc_class;\n";
565   Preamble += "struct __rw_objc_super { struct objc_object *object; ";
566   Preamble += "struct objc_object *superClass; ";
567   if (LangOpts.Microsoft) {
568     // Add a constructor for creating temporary objects.
569     Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) "
570                 ": ";
571     Preamble += "object(o), superClass(s) {} ";
572   }
573   Preamble += "};\n";
574   Preamble += "#ifndef _REWRITER_typedef_Protocol\n";
575   Preamble += "typedef struct objc_object Protocol;\n";
576   Preamble += "#define _REWRITER_typedef_Protocol\n";
577   Preamble += "#endif\n";
578   if (LangOpts.Microsoft) {
579     Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
580     Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
581   } else
582   Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
583   Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend";
584   Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
585   Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper";
586   Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
587   Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend_stret";
588   Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
589   Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper_stret";
590   Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
591   Preamble += "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret";
592   Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
593   Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass";
594   Preamble += "(const char *);\n";
595   Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
596   Preamble += "(struct objc_class *);\n";
597   Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
598   Preamble += "(const char *);\n";
599   Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
600   Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n";
601   Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n";
602   Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n";
603   Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match";
604   Preamble += "(struct objc_class *, struct objc_object *);\n";
605   // @synchronized hooks.
606   Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_enter(struct objc_object *);\n";
607   Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_exit(struct objc_object *);\n";
608   Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
609   Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
610   Preamble += "struct __objcFastEnumerationState {\n\t";
611   Preamble += "unsigned long state;\n\t";
612   Preamble += "void **itemsPtr;\n\t";
613   Preamble += "unsigned long *mutationsPtr;\n\t";
614   Preamble += "unsigned long extra[5];\n};\n";
615   Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
616   Preamble += "#define __FASTENUMERATIONSTATE\n";
617   Preamble += "#endif\n";
618   Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n";
619   Preamble += "struct __NSConstantStringImpl {\n";
620   Preamble += "  int *isa;\n";
621   Preamble += "  int flags;\n";
622   Preamble += "  char *str;\n";
623   Preamble += "  long length;\n";
624   Preamble += "};\n";
625   Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n";
626   Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
627   Preamble += "#else\n";
628   Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
629   Preamble += "#endif\n";
630   Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
631   Preamble += "#endif\n";
632   // Blocks preamble.
633   Preamble += "#ifndef BLOCK_IMPL\n";
634   Preamble += "#define BLOCK_IMPL\n";
635   Preamble += "struct __block_impl {\n";
636   Preamble += "  void *isa;\n";
637   Preamble += "  int Flags;\n";
638   Preamble += "  int Reserved;\n";
639   Preamble += "  void *FuncPtr;\n";
640   Preamble += "};\n";
641   Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
642   Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n";
643   Preamble += "extern \"C\" __declspec(dllexport) "
644               "void _Block_object_assign(void *, const void *, const int);\n";
645   Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
646   Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
647   Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
648   Preamble += "#else\n";
649   Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
650   Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
651   Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
652   Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
653   Preamble += "#endif\n";
654   Preamble += "#endif\n";
655   if (LangOpts.Microsoft) {
656     Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
657     Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
658     Preamble += "#ifndef KEEP_ATTRIBUTES\n";  // We use this for clang tests.
659     Preamble += "#define __attribute__(X)\n";
660     Preamble += "#endif\n";
661     Preamble += "#define __weak\n";
662   }
663   else {
664     Preamble += "#define __block\n";
665     Preamble += "#define __weak\n";
666   }
667   // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
668   // as this avoids warning in any 64bit/32bit compilation model.
669   Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
670 }
671
672
673 //===----------------------------------------------------------------------===//
674 // Top Level Driver Code
675 //===----------------------------------------------------------------------===//
676
677 void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
678   if (Diags.hasErrorOccurred())
679     return;
680
681   // Two cases: either the decl could be in the main file, or it could be in a
682   // #included file.  If the former, rewrite it now.  If the later, check to see
683   // if we rewrote the #include/#import.
684   SourceLocation Loc = D->getLocation();
685   Loc = SM->getInstantiationLoc(Loc);
686
687   // If this is for a builtin, ignore it.
688   if (Loc.isInvalid()) return;
689
690   // Look for built-in declarations that we need to refer during the rewrite.
691   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
692     RewriteFunctionDecl(FD);
693   } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
694     // declared in <Foundation/NSString.h>
695     if (strcmp(FVD->getNameAsCString(), "_NSConstantStringClassReference") == 0) {
696       ConstantStringClassReference = FVD;
697       return;
698     }
699   } else if (ObjCInterfaceDecl *MD = dyn_cast<ObjCInterfaceDecl>(D)) {
700     RewriteInterfaceDecl(MD);
701   } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
702     RewriteCategoryDecl(CD);
703   } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
704     RewriteProtocolDecl(PD);
705   } else if (ObjCForwardProtocolDecl *FP =
706              dyn_cast<ObjCForwardProtocolDecl>(D)){
707     RewriteForwardProtocolDecl(FP);
708   } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
709     // Recurse into linkage specifications
710     for (DeclContext::decl_iterator DI = LSD->decls_begin(),
711                                  DIEnd = LSD->decls_end();
712          DI != DIEnd; ++DI)
713       HandleTopLevelSingleDecl(*DI);
714   }
715   // If we have a decl in the main file, see if we should rewrite it.
716   if (SM->isFromMainFile(Loc))
717     return HandleDeclInMainFile(D);
718 }
719
720 //===----------------------------------------------------------------------===//
721 // Syntactic (non-AST) Rewriting Code
722 //===----------------------------------------------------------------------===//
723
724 void RewriteObjC::RewriteInclude() {
725   SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
726   llvm::StringRef MainBuf = SM->getBufferData(MainFileID);
727   const char *MainBufStart = MainBuf.begin();
728   const char *MainBufEnd = MainBuf.end();
729   size_t ImportLen = strlen("import");
730
731   // Loop over the whole file, looking for includes.
732   for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
733     if (*BufPtr == '#') {
734       if (++BufPtr == MainBufEnd)
735         return;
736       while (*BufPtr == ' ' || *BufPtr == '\t')
737         if (++BufPtr == MainBufEnd)
738           return;
739       if (!strncmp(BufPtr, "import", ImportLen)) {
740         // replace import with include
741         SourceLocation ImportLoc =
742           LocStart.getFileLocWithOffset(BufPtr-MainBufStart);
743         ReplaceText(ImportLoc, ImportLen, "include");
744         BufPtr += ImportLen;
745       }
746     }
747   }
748 }
749
750 void RewriteObjC::RewriteTabs() {
751   llvm::StringRef MainBuf = SM->getBufferData(MainFileID);
752   const char *MainBufStart = MainBuf.begin();
753   const char *MainBufEnd = MainBuf.end();
754
755   // Loop over the whole file, looking for tabs.
756   for (const char *BufPtr = MainBufStart; BufPtr != MainBufEnd; ++BufPtr) {
757     if (*BufPtr != '\t')
758       continue;
759
760     // Okay, we found a tab.  This tab will turn into at least one character,
761     // but it depends on which 'virtual column' it is in.  Compute that now.
762     unsigned VCol = 0;
763     while (BufPtr-VCol != MainBufStart && BufPtr[-VCol-1] != '\t' &&
764            BufPtr[-VCol-1] != '\n' && BufPtr[-VCol-1] != '\r')
765       ++VCol;
766
767     // Okay, now that we know the virtual column, we know how many spaces to
768     // insert.  We assume 8-character tab-stops.
769     unsigned Spaces = 8-(VCol & 7);
770
771     // Get the location of the tab.
772     SourceLocation TabLoc = SM->getLocForStartOfFile(MainFileID);
773     TabLoc = TabLoc.getFileLocWithOffset(BufPtr-MainBufStart);
774
775     // Rewrite the single tab character into a sequence of spaces.
776     ReplaceText(TabLoc, 1, llvm::StringRef("        ", Spaces));
777   }
778 }
779
780 static std::string getIvarAccessString(ObjCInterfaceDecl *ClassDecl,
781                                        ObjCIvarDecl *OID) {
782   std::string S;
783   S = "((struct ";
784   S += ClassDecl->getIdentifier()->getName();
785   S += "_IMPL *)self)->";
786   S += OID->getName();
787   return S;
788 }
789
790 void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
791                                           ObjCImplementationDecl *IMD,
792                                           ObjCCategoryImplDecl *CID) {
793   static bool objcGetPropertyDefined = false;
794   static bool objcSetPropertyDefined = false;
795   SourceLocation startLoc = PID->getLocStart();
796   InsertText(startLoc, "// ");
797   const char *startBuf = SM->getCharacterData(startLoc);
798   assert((*startBuf == '@') && "bogus @synthesize location");
799   const char *semiBuf = strchr(startBuf, ';');
800   assert((*semiBuf == ';') && "@synthesize: can't find ';'");
801   SourceLocation onePastSemiLoc =
802     startLoc.getFileLocWithOffset(semiBuf-startBuf+1);
803
804   if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
805     return; // FIXME: is this correct?
806
807   // Generate the 'getter' function.
808   ObjCPropertyDecl *PD = PID->getPropertyDecl();
809   ObjCInterfaceDecl *ClassDecl = PD->getGetterMethodDecl()->getClassInterface();
810   ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
811
812   if (!OID)
813     return;
814   unsigned Attributes = PD->getPropertyAttributes();
815   bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
816                          (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
817                                         ObjCPropertyDecl::OBJC_PR_copy));
818   std::string Getr;
819   if (GenGetProperty && !objcGetPropertyDefined) {
820     objcGetPropertyDefined = true;
821     // FIXME. Is this attribute correct in all cases?
822     Getr = "\nextern \"C\" __declspec(dllimport) "
823            "id objc_getProperty(id, SEL, long, bool);\n";
824   }
825   RewriteObjCMethodDecl(PD->getGetterMethodDecl(), Getr);
826   Getr += "{ ";
827   // Synthesize an explicit cast to gain access to the ivar.
828   // See objc-act.c:objc_synthesize_new_getter() for details.
829   if (GenGetProperty) {
830     // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
831     Getr += "typedef ";
832     const FunctionType *FPRetType = 0;
833     RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr, 
834                           FPRetType);
835     Getr += " _TYPE";
836     if (FPRetType) {
837       Getr += ")"; // close the precedence "scope" for "*".
838       
839       // Now, emit the argument types (if any).
840       if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){
841         Getr += "(";
842         for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
843           if (i) Getr += ", ";
844           std::string ParamStr = FT->getArgType(i).getAsString(
845             Context->PrintingPolicy);
846           Getr += ParamStr;
847         }
848         if (FT->isVariadic()) {
849           if (FT->getNumArgs()) Getr += ", ";
850           Getr += "...";
851         }
852         Getr += ")";
853       } else
854         Getr += "()";
855     }
856     Getr += ";\n";
857     Getr += "return (_TYPE)";
858     Getr += "objc_getProperty(self, _cmd, ";
859     SynthesizeIvarOffsetComputation(ClassDecl, OID, Getr);
860     Getr += ", 1)";
861   }
862   else
863     Getr += "return " + getIvarAccessString(ClassDecl, OID);
864   Getr += "; }";
865   InsertText(onePastSemiLoc, Getr);
866   if (PD->isReadOnly())
867     return;
868
869   // Generate the 'setter' function.
870   std::string Setr;
871   bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
872                                       ObjCPropertyDecl::OBJC_PR_copy);
873   if (GenSetProperty && !objcSetPropertyDefined) {
874     objcSetPropertyDefined = true;
875     // FIXME. Is this attribute correct in all cases?
876     Setr = "\nextern \"C\" __declspec(dllimport) "
877     "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
878   }
879   
880   RewriteObjCMethodDecl(PD->getSetterMethodDecl(), Setr);
881   Setr += "{ ";
882   // Synthesize an explicit cast to initialize the ivar.
883   // See objc-act.c:objc_synthesize_new_setter() for details.
884   if (GenSetProperty) {
885     Setr += "objc_setProperty (self, _cmd, ";
886     SynthesizeIvarOffsetComputation(ClassDecl, OID, Setr);
887     Setr += ", (id)";
888     Setr += PD->getNameAsCString();
889     Setr += ", ";
890     if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
891       Setr += "0, ";
892     else
893       Setr += "1, ";
894     if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
895       Setr += "1)";
896     else
897       Setr += "0)";
898   }
899   else {
900     Setr += getIvarAccessString(ClassDecl, OID) + " = ";
901     Setr += PD->getNameAsCString();
902   }
903   Setr += "; }";
904   InsertText(onePastSemiLoc, Setr);
905 }
906
907 void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) {
908   // Get the start location and compute the semi location.
909   SourceLocation startLoc = ClassDecl->getLocation();
910   const char *startBuf = SM->getCharacterData(startLoc);
911   const char *semiPtr = strchr(startBuf, ';');
912
913   // Translate to typedef's that forward reference structs with the same name
914   // as the class. As a convenience, we include the original declaration
915   // as a comment.
916   std::string typedefString;
917   typedefString += "// @class ";
918   for (ObjCClassDecl::iterator I = ClassDecl->begin(), E = ClassDecl->end();
919        I != E; ++I) {
920     ObjCInterfaceDecl *ForwardDecl = I->getInterface();
921     typedefString += ForwardDecl->getNameAsString();
922     if (I+1 != E)
923       typedefString += ", ";
924     else
925       typedefString += ";\n";
926   }
927   
928   for (ObjCClassDecl::iterator I = ClassDecl->begin(), E = ClassDecl->end();
929        I != E; ++I) {
930     ObjCInterfaceDecl *ForwardDecl = I->getInterface();
931     typedefString += "#ifndef _REWRITER_typedef_";
932     typedefString += ForwardDecl->getNameAsString();
933     typedefString += "\n";
934     typedefString += "#define _REWRITER_typedef_";
935     typedefString += ForwardDecl->getNameAsString();
936     typedefString += "\n";
937     typedefString += "typedef struct objc_object ";
938     typedefString += ForwardDecl->getNameAsString();
939     typedefString += ";\n#endif\n";
940   }
941
942   // Replace the @class with typedefs corresponding to the classes.
943   ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
944 }
945
946 void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
947   // When method is a synthesized one, such as a getter/setter there is
948   // nothing to rewrite.
949   if (Method->isSynthesized())
950     return;
951   SourceLocation LocStart = Method->getLocStart();
952   SourceLocation LocEnd = Method->getLocEnd();
953
954   if (SM->getInstantiationLineNumber(LocEnd) >
955       SM->getInstantiationLineNumber(LocStart)) {
956     InsertText(LocStart, "#if 0\n");
957     ReplaceText(LocEnd, 1, ";\n#endif\n");
958   } else {
959     InsertText(LocStart, "// ");
960   }
961 }
962
963 void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) {
964   SourceLocation Loc = prop->getAtLoc();
965
966   ReplaceText(Loc, 0, "// ");
967   // FIXME: handle properties that are declared across multiple lines.
968 }
969
970 void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
971   SourceLocation LocStart = CatDecl->getLocStart();
972
973   // FIXME: handle category headers that are declared across multiple lines.
974   ReplaceText(LocStart, 0, "// ");
975
976   for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(),
977        E = CatDecl->prop_end(); I != E; ++I)
978     RewriteProperty(*I);
979   
980   for (ObjCCategoryDecl::instmeth_iterator
981          I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
982        I != E; ++I)
983     RewriteMethodDeclaration(*I);
984   for (ObjCCategoryDecl::classmeth_iterator
985          I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
986        I != E; ++I)
987     RewriteMethodDeclaration(*I);
988
989   // Lastly, comment out the @end.
990   ReplaceText(CatDecl->getAtEndRange().getBegin(), 
991               strlen("@end"), "/* @end */");
992 }
993
994 void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
995   SourceLocation LocStart = PDecl->getLocStart();
996
997   // FIXME: handle protocol headers that are declared across multiple lines.
998   ReplaceText(LocStart, 0, "// ");
999
1000   for (ObjCProtocolDecl::instmeth_iterator
1001          I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
1002        I != E; ++I)
1003     RewriteMethodDeclaration(*I);
1004   for (ObjCProtocolDecl::classmeth_iterator
1005          I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
1006        I != E; ++I)
1007     RewriteMethodDeclaration(*I);
1008
1009   // Lastly, comment out the @end.
1010   SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
1011   ReplaceText(LocEnd, strlen("@end"), "/* @end */");
1012
1013   // Must comment out @optional/@required
1014   const char *startBuf = SM->getCharacterData(LocStart);
1015   const char *endBuf = SM->getCharacterData(LocEnd);
1016   for (const char *p = startBuf; p < endBuf; p++) {
1017     if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
1018       SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
1019       ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
1020
1021     }
1022     else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
1023       SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
1024       ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
1025
1026     }
1027   }
1028 }
1029
1030 void RewriteObjC::RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *PDecl) {
1031   SourceLocation LocStart = PDecl->getLocation();
1032   if (LocStart.isInvalid())
1033     assert(false && "Invalid SourceLocation");
1034   // FIXME: handle forward protocol that are declared across multiple lines.
1035   ReplaceText(LocStart, 0, "// ");
1036 }
1037
1038 void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
1039                                         const FunctionType *&FPRetType) {
1040   if (T->isObjCQualifiedIdType())
1041     ResultStr += "id";
1042   else if (T->isFunctionPointerType() ||
1043            T->isBlockPointerType()) {
1044     // needs special handling, since pointer-to-functions have special
1045     // syntax (where a decaration models use).
1046     QualType retType = T;
1047     QualType PointeeTy;
1048     if (const PointerType* PT = retType->getAs<PointerType>())
1049       PointeeTy = PT->getPointeeType();
1050     else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>())
1051       PointeeTy = BPT->getPointeeType();
1052     if ((FPRetType = PointeeTy->getAs<FunctionType>())) {
1053       ResultStr += FPRetType->getResultType().getAsString(
1054         Context->PrintingPolicy);
1055       ResultStr += "(*";
1056     }
1057   } else
1058     ResultStr += T.getAsString(Context->PrintingPolicy);
1059 }
1060
1061 void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
1062                                         std::string &ResultStr) {
1063   //fprintf(stderr,"In RewriteObjCMethodDecl\n");
1064   const FunctionType *FPRetType = 0;
1065   ResultStr += "\nstatic ";
1066   RewriteTypeIntoString(OMD->getResultType(), ResultStr, FPRetType);
1067   ResultStr += " ";
1068
1069   // Unique method name
1070   std::string NameStr;
1071
1072   if (OMD->isInstanceMethod())
1073     NameStr += "_I_";
1074   else
1075     NameStr += "_C_";
1076
1077   NameStr += OMD->getClassInterface()->getNameAsString();
1078   NameStr += "_";
1079
1080   if (ObjCCategoryImplDecl *CID =
1081       dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
1082     NameStr += CID->getNameAsString();
1083     NameStr += "_";
1084   }
1085   // Append selector names, replacing ':' with '_'
1086   {
1087     std::string selString = OMD->getSelector().getAsString();
1088     int len = selString.size();
1089     for (int i = 0; i < len; i++)
1090       if (selString[i] == ':')
1091         selString[i] = '_';
1092     NameStr += selString;
1093   }
1094   // Remember this name for metadata emission
1095   MethodInternalNames[OMD] = NameStr;
1096   ResultStr += NameStr;
1097
1098   // Rewrite arguments
1099   ResultStr += "(";
1100
1101   // invisible arguments
1102   if (OMD->isInstanceMethod()) {
1103     QualType selfTy = Context->getObjCInterfaceType(OMD->getClassInterface());
1104     selfTy = Context->getPointerType(selfTy);
1105     if (!LangOpts.Microsoft) {
1106       if (ObjCSynthesizedStructs.count(OMD->getClassInterface()))
1107         ResultStr += "struct ";
1108     }
1109     // When rewriting for Microsoft, explicitly omit the structure name.
1110     ResultStr += OMD->getClassInterface()->getNameAsString();
1111     ResultStr += " *";
1112   }
1113   else
1114     ResultStr += Context->getObjCClassType().getAsString(
1115       Context->PrintingPolicy);
1116
1117   ResultStr += " self, ";
1118   ResultStr += Context->getObjCSelType().getAsString(Context->PrintingPolicy);
1119   ResultStr += " _cmd";
1120
1121   // Method arguments.
1122   for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
1123        E = OMD->param_end(); PI != E; ++PI) {
1124     ParmVarDecl *PDecl = *PI;
1125     ResultStr += ", ";
1126     if (PDecl->getType()->isObjCQualifiedIdType()) {
1127       ResultStr += "id ";
1128       ResultStr += PDecl->getNameAsString();
1129     } else {
1130       std::string Name = PDecl->getNameAsString();
1131       QualType QT = PDecl->getType();
1132       // Make sure we convert "t (^)(...)" to "t (*)(...)".
1133       if (convertBlockPointerToFunctionPointer(QT))
1134         QT.getAsStringInternal(Name, Context->PrintingPolicy);
1135       else
1136         PDecl->getType().getAsStringInternal(Name, Context->PrintingPolicy);
1137       ResultStr += Name;
1138     }
1139   }
1140   if (OMD->isVariadic())
1141     ResultStr += ", ...";
1142   ResultStr += ") ";
1143
1144   if (FPRetType) {
1145     ResultStr += ")"; // close the precedence "scope" for "*".
1146
1147     // Now, emit the argument types (if any).
1148     if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
1149       ResultStr += "(";
1150       for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
1151         if (i) ResultStr += ", ";
1152         std::string ParamStr = FT->getArgType(i).getAsString(
1153           Context->PrintingPolicy);
1154         ResultStr += ParamStr;
1155       }
1156       if (FT->isVariadic()) {
1157         if (FT->getNumArgs()) ResultStr += ", ";
1158         ResultStr += "...";
1159       }
1160       ResultStr += ")";
1161     } else {
1162       ResultStr += "()";
1163     }
1164   }
1165 }
1166 void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
1167   ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
1168   ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
1169
1170   InsertText(IMD ? IMD->getLocStart() : CID->getLocStart(), "// ");
1171
1172   for (ObjCCategoryImplDecl::instmeth_iterator
1173        I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
1174        E = IMD ? IMD->instmeth_end() : CID->instmeth_end();
1175        I != E; ++I) {
1176     std::string ResultStr;
1177     ObjCMethodDecl *OMD = *I;
1178     RewriteObjCMethodDecl(OMD, ResultStr);
1179     SourceLocation LocStart = OMD->getLocStart();
1180     SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
1181
1182     const char *startBuf = SM->getCharacterData(LocStart);
1183     const char *endBuf = SM->getCharacterData(LocEnd);
1184     ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1185   }
1186
1187   for (ObjCCategoryImplDecl::classmeth_iterator
1188        I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(),
1189        E = IMD ? IMD->classmeth_end() : CID->classmeth_end();
1190        I != E; ++I) {
1191     std::string ResultStr;
1192     ObjCMethodDecl *OMD = *I;
1193     RewriteObjCMethodDecl(OMD, ResultStr);
1194     SourceLocation LocStart = OMD->getLocStart();
1195     SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
1196
1197     const char *startBuf = SM->getCharacterData(LocStart);
1198     const char *endBuf = SM->getCharacterData(LocEnd);
1199     ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1200   }
1201   for (ObjCCategoryImplDecl::propimpl_iterator
1202        I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
1203        E = IMD ? IMD->propimpl_end() : CID->propimpl_end();
1204        I != E; ++I) {
1205     RewritePropertyImplDecl(*I, IMD, CID);
1206   }
1207
1208   InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
1209 }
1210
1211 void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
1212   std::string ResultStr;
1213   if (!ObjCForwardDecls.count(ClassDecl)) {
1214     // we haven't seen a forward decl - generate a typedef.
1215     ResultStr = "#ifndef _REWRITER_typedef_";
1216     ResultStr += ClassDecl->getNameAsString();
1217     ResultStr += "\n";
1218     ResultStr += "#define _REWRITER_typedef_";
1219     ResultStr += ClassDecl->getNameAsString();
1220     ResultStr += "\n";
1221     ResultStr += "typedef struct objc_object ";
1222     ResultStr += ClassDecl->getNameAsString();
1223     ResultStr += ";\n#endif\n";
1224     // Mark this typedef as having been generated.
1225     ObjCForwardDecls.insert(ClassDecl);
1226   }
1227   SynthesizeObjCInternalStruct(ClassDecl, ResultStr);
1228
1229   for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(),
1230          E = ClassDecl->prop_end(); I != E; ++I)
1231     RewriteProperty(*I);
1232   for (ObjCInterfaceDecl::instmeth_iterator
1233          I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
1234        I != E; ++I)
1235     RewriteMethodDeclaration(*I);
1236   for (ObjCInterfaceDecl::classmeth_iterator
1237          I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
1238        I != E; ++I)
1239     RewriteMethodDeclaration(*I);
1240
1241   // Lastly, comment out the @end.
1242   ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
1243               "/* @end */");
1244 }
1245
1246 Stmt *RewriteObjC::RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
1247                                          SourceRange SrcRange) {
1248   // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr.
1249   // This allows us to reuse all the fun and games in SynthMessageExpr().
1250   ObjCPropertyRefExpr *PropRefExpr = dyn_cast<ObjCPropertyRefExpr>(BinOp->getLHS());
1251   ObjCMessageExpr *MsgExpr;
1252   ObjCPropertyDecl *PDecl = PropRefExpr->getProperty();
1253   llvm::SmallVector<Expr *, 1> ExprVec;
1254   ExprVec.push_back(newStmt);
1255
1256   Stmt *Receiver = PropRefExpr->getBase();
1257   ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(Receiver);
1258   if (PRE && PropGetters[PRE]) {
1259     // This allows us to handle chain/nested property getters.
1260     Receiver = PropGetters[PRE];
1261   }
1262   if (isa<ObjCSuperExpr>(Receiver))
1263     MsgExpr = ObjCMessageExpr::Create(*Context, 
1264                                       PDecl->getType().getNonReferenceType(),
1265                                       /*FIXME?*/SourceLocation(),
1266                                       Receiver->getLocStart(),
1267                                       /*IsInstanceSuper=*/true,
1268                                       cast<Expr>(Receiver)->getType(),
1269                                       PDecl->getSetterName(),
1270                                       PDecl->getSetterMethodDecl(),
1271                                       &ExprVec[0], 1,
1272                                       /*FIXME:*/SourceLocation());
1273   else
1274     MsgExpr = ObjCMessageExpr::Create(*Context, 
1275                                       PDecl->getType().getNonReferenceType(),
1276                                       /*FIXME: */SourceLocation(),
1277                                       cast<Expr>(Receiver),
1278                                       PDecl->getSetterName(),
1279                                       PDecl->getSetterMethodDecl(),
1280                                       &ExprVec[0], 1,
1281                                       /*FIXME:*/SourceLocation());
1282   Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
1283
1284   // Now do the actual rewrite.
1285   ReplaceStmtWithRange(BinOp, ReplacingStmt, SrcRange);
1286   //delete BinOp;
1287   // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
1288   // to things that stay around.
1289   Context->Deallocate(MsgExpr);
1290   return ReplacingStmt;
1291 }
1292
1293 Stmt *RewriteObjC::RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr) {
1294   // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr.
1295   // This allows us to reuse all the fun and games in SynthMessageExpr().
1296   ObjCMessageExpr *MsgExpr;
1297   ObjCPropertyDecl *PDecl = PropRefExpr->getProperty();
1298
1299   Stmt *Receiver = PropRefExpr->getBase();
1300
1301   ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(Receiver);
1302   if (PRE && PropGetters[PRE]) {
1303     // This allows us to handle chain/nested property getters.
1304     Receiver = PropGetters[PRE];
1305   }
1306
1307   if (isa<ObjCSuperExpr>(Receiver))
1308     MsgExpr = ObjCMessageExpr::Create(*Context, 
1309                                       PDecl->getType().getNonReferenceType(),
1310                                       /*FIXME:*/SourceLocation(),
1311                                       Receiver->getLocStart(),
1312                                       /*IsInstanceSuper=*/true,
1313                                       cast<Expr>(Receiver)->getType(),
1314                                       PDecl->getGetterName(), 
1315                                       PDecl->getGetterMethodDecl(),
1316                                       0, 0, 
1317                                       /*FIXME:*/SourceLocation());
1318   else
1319     MsgExpr = ObjCMessageExpr::Create(*Context, 
1320                                       PDecl->getType().getNonReferenceType(),
1321                                       /*FIXME:*/SourceLocation(),
1322                                       cast<Expr>(Receiver),
1323                                       PDecl->getGetterName(), 
1324                                       PDecl->getGetterMethodDecl(),
1325                                       0, 0, 
1326                                       /*FIXME:*/SourceLocation());
1327
1328   Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
1329
1330   if (!PropParentMap)
1331     PropParentMap = new ParentMap(CurrentBody);
1332
1333   Stmt *Parent = PropParentMap->getParent(PropRefExpr);
1334   if (Parent && isa<ObjCPropertyRefExpr>(Parent)) {
1335     // We stash away the ReplacingStmt since actually doing the
1336     // replacement/rewrite won't work for nested getters (e.g. obj.p.i)
1337     PropGetters[PropRefExpr] = ReplacingStmt;
1338     // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
1339     // to things that stay around.
1340     Context->Deallocate(MsgExpr);
1341     return PropRefExpr; // return the original...
1342   } else {
1343     ReplaceStmt(PropRefExpr, ReplacingStmt);
1344     // delete PropRefExpr; elsewhere...
1345     // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
1346     // to things that stay around.
1347     Context->Deallocate(MsgExpr);
1348     return ReplacingStmt;
1349   }
1350 }
1351
1352 Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
1353                                           SourceLocation OrigStart,
1354                                           bool &replaced) {
1355   ObjCIvarDecl *D = IV->getDecl();
1356   const Expr *BaseExpr = IV->getBase();
1357   if (CurMethodDef) {
1358     if (BaseExpr->getType()->isObjCObjectPointerType()) {
1359       ObjCInterfaceType *iFaceDecl =
1360         dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
1361       assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
1362       // lookup which class implements the instance variable.
1363       ObjCInterfaceDecl *clsDeclared = 0;
1364       iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
1365                                                    clsDeclared);
1366       assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
1367
1368       // Synthesize an explicit cast to gain access to the ivar.
1369       std::string RecName = clsDeclared->getIdentifier()->getName();
1370       RecName += "_IMPL";
1371       IdentifierInfo *II = &Context->Idents.get(RecName);
1372       RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
1373                                           SourceLocation(), II);
1374       assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
1375       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
1376       CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
1377                                                     CastExpr::CK_Unknown,
1378                                                     IV->getBase());
1379       // Don't forget the parens to enforce the proper binding.
1380       ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
1381                                                IV->getBase()->getLocEnd(),
1382                                                castExpr);
1383       replaced = true;
1384       if (IV->isFreeIvar() &&
1385           CurMethodDef->getClassInterface() == iFaceDecl->getDecl()) {
1386         MemberExpr *ME = new (Context) MemberExpr(PE, true, D,
1387                                                    IV->getLocation(),
1388                                                    D->getType());
1389         // delete IV; leak for now, see RewritePropertySetter() usage for more info.
1390         return ME;
1391       }
1392       // Get the new text
1393       // Cannot delete IV->getBase(), since PE points to it.
1394       // Replace the old base with the cast. This is important when doing
1395       // embedded rewrites. For example, [newInv->_container addObject:0].
1396       IV->setBase(PE);
1397       return IV;
1398     }
1399   } else { // we are outside a method.
1400     assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method");
1401
1402     // Explicit ivar refs need to have a cast inserted.
1403     // FIXME: consider sharing some of this code with the code above.
1404     if (BaseExpr->getType()->isObjCObjectPointerType()) {
1405       ObjCInterfaceType *iFaceDecl =
1406         dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
1407       // lookup which class implements the instance variable.
1408       ObjCInterfaceDecl *clsDeclared = 0;
1409       iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
1410                                                    clsDeclared);
1411       assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
1412
1413       // Synthesize an explicit cast to gain access to the ivar.
1414       std::string RecName = clsDeclared->getIdentifier()->getName();
1415       RecName += "_IMPL";
1416       IdentifierInfo *II = &Context->Idents.get(RecName);
1417       RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
1418                                           SourceLocation(), II);
1419       assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
1420       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
1421       CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
1422                                                     CastExpr::CK_Unknown,
1423                                                     IV->getBase());
1424       // Don't forget the parens to enforce the proper binding.
1425       ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
1426                                     IV->getBase()->getLocEnd(), castExpr);
1427       replaced = true;
1428       // Cannot delete IV->getBase(), since PE points to it.
1429       // Replace the old base with the cast. This is important when doing
1430       // embedded rewrites. For example, [newInv->_container addObject:0].
1431       IV->setBase(PE);
1432       return IV;
1433     }
1434   }
1435   return IV;
1436 }
1437
1438 Stmt *RewriteObjC::RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced) {
1439   for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
1440        CI != E; ++CI) {
1441     if (*CI) {
1442       Stmt *newStmt = RewriteObjCNestedIvarRefExpr(*CI, replaced);
1443       if (newStmt)
1444         *CI = newStmt;
1445     }
1446   }
1447   if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
1448     SourceRange OrigStmtRange = S->getSourceRange();
1449     Stmt *newStmt = RewriteObjCIvarRefExpr(IvarRefExpr, OrigStmtRange.getBegin(),
1450                                            replaced);
1451     return newStmt;
1452   } 
1453   if (ObjCMessageExpr *MsgRefExpr = dyn_cast<ObjCMessageExpr>(S)) {
1454     Stmt *newStmt = SynthMessageExpr(MsgRefExpr);
1455     return newStmt;
1456   }
1457   return S;
1458 }
1459
1460 /// SynthCountByEnumWithState - To print:
1461 /// ((unsigned int (*)
1462 ///  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
1463 ///  (void *)objc_msgSend)((id)l_collection,
1464 ///                        sel_registerName(
1465 ///                          "countByEnumeratingWithState:objects:count:"),
1466 ///                        &enumState,
1467 ///                        (id *)items, (unsigned int)16)
1468 ///
1469 void RewriteObjC::SynthCountByEnumWithState(std::string &buf) {
1470   buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, "
1471   "id *, unsigned int))(void *)objc_msgSend)";
1472   buf += "\n\t\t";
1473   buf += "((id)l_collection,\n\t\t";
1474   buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1475   buf += "\n\t\t";
1476   buf += "&enumState, "
1477          "(id *)items, (unsigned int)16)";
1478 }
1479
1480 /// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
1481 /// statement to exit to its outer synthesized loop.
1482 ///
1483 Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) {
1484   if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1485     return S;
1486   // replace break with goto __break_label
1487   std::string buf;
1488
1489   SourceLocation startLoc = S->getLocStart();
1490   buf = "goto __break_label_";
1491   buf += utostr(ObjCBcLabelNo.back());
1492   ReplaceText(startLoc, strlen("break"), buf);
1493
1494   return 0;
1495 }
1496
1497 /// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
1498 /// statement to continue with its inner synthesized loop.
1499 ///
1500 Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) {
1501   if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1502     return S;
1503   // replace continue with goto __continue_label
1504   std::string buf;
1505
1506   SourceLocation startLoc = S->getLocStart();
1507   buf = "goto __continue_label_";
1508   buf += utostr(ObjCBcLabelNo.back());
1509   ReplaceText(startLoc, strlen("continue"), buf);
1510
1511   return 0;
1512 }
1513
1514 /// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
1515 ///  It rewrites:
1516 /// for ( type elem in collection) { stmts; }
1517
1518 /// Into:
1519 /// {
1520 ///   type elem;
1521 ///   struct __objcFastEnumerationState enumState = { 0 };
1522 ///   id items[16];
1523 ///   id l_collection = (id)collection;
1524 ///   unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
1525 ///                                       objects:items count:16];
1526 /// if (limit) {
1527 ///   unsigned long startMutations = *enumState.mutationsPtr;
1528 ///   do {
1529 ///        unsigned long counter = 0;
1530 ///        do {
1531 ///             if (startMutations != *enumState.mutationsPtr)
1532 ///               objc_enumerationMutation(l_collection);
1533 ///             elem = (type)enumState.itemsPtr[counter++];
1534 ///             stmts;
1535 ///             __continue_label: ;
1536 ///        } while (counter < limit);
1537 ///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
1538 ///                                  objects:items count:16]);
1539 ///   elem = nil;
1540 ///   __break_label: ;
1541 ///  }
1542 ///  else
1543 ///       elem = nil;
1544 ///  }
1545 ///
1546 Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
1547                                                 SourceLocation OrigEnd) {
1548   assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty");
1549   assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1550          "ObjCForCollectionStmt Statement stack mismatch");
1551   assert(!ObjCBcLabelNo.empty() &&
1552          "ObjCForCollectionStmt - Label No stack empty");
1553
1554   SourceLocation startLoc = S->getLocStart();
1555   const char *startBuf = SM->getCharacterData(startLoc);
1556   const char *elementName;
1557   std::string elementTypeAsString;
1558   std::string buf;
1559   buf = "\n{\n\t";
1560   if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
1561     // type elem;
1562     NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
1563     QualType ElementType = cast<ValueDecl>(D)->getType();
1564     if (ElementType->isObjCQualifiedIdType() ||
1565         ElementType->isObjCQualifiedInterfaceType())
1566       // Simply use 'id' for all qualified types.
1567       elementTypeAsString = "id";
1568     else
1569       elementTypeAsString = ElementType.getAsString(Context->PrintingPolicy);
1570     buf += elementTypeAsString;
1571     buf += " ";
1572     elementName = D->getNameAsCString();
1573     buf += elementName;
1574     buf += ";\n\t";
1575   }
1576   else {
1577     DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
1578     elementName = DR->getDecl()->getNameAsCString();
1579     ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
1580     if (VD->getType()->isObjCQualifiedIdType() ||
1581         VD->getType()->isObjCQualifiedInterfaceType())
1582       // Simply use 'id' for all qualified types.
1583       elementTypeAsString = "id";
1584     else
1585       elementTypeAsString = VD->getType().getAsString(Context->PrintingPolicy);
1586   }
1587
1588   // struct __objcFastEnumerationState enumState = { 0 };
1589   buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
1590   // id items[16];
1591   buf += "id items[16];\n\t";
1592   // id l_collection = (id)
1593   buf += "id l_collection = (id)";
1594   // Find start location of 'collection' the hard way!
1595   const char *startCollectionBuf = startBuf;
1596   startCollectionBuf += 3;  // skip 'for'
1597   startCollectionBuf = strchr(startCollectionBuf, '(');
1598   startCollectionBuf++; // skip '('
1599   // find 'in' and skip it.
1600   while (*startCollectionBuf != ' ' ||
1601          *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' ||
1602          (*(startCollectionBuf+3) != ' ' &&
1603           *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '('))
1604     startCollectionBuf++;
1605   startCollectionBuf += 3;
1606
1607   // Replace: "for (type element in" with string constructed thus far.
1608   ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1609   // Replace ')' in for '(' type elem in collection ')' with ';'
1610   SourceLocation rightParenLoc = S->getRParenLoc();
1611   const char *rparenBuf = SM->getCharacterData(rightParenLoc);
1612   SourceLocation lparenLoc = startLoc.getFileLocWithOffset(rparenBuf-startBuf);
1613   buf = ";\n\t";
1614
1615   // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
1616   //                                   objects:items count:16];
1617   // which is synthesized into:
1618   // unsigned int limit =
1619   // ((unsigned int (*)
1620   //  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
1621   //  (void *)objc_msgSend)((id)l_collection,
1622   //                        sel_registerName(
1623   //                          "countByEnumeratingWithState:objects:count:"),
1624   //                        (struct __objcFastEnumerationState *)&state,
1625   //                        (id *)items, (unsigned int)16);
1626   buf += "unsigned long limit =\n\t\t";
1627   SynthCountByEnumWithState(buf);
1628   buf += ";\n\t";
1629   /// if (limit) {
1630   ///   unsigned long startMutations = *enumState.mutationsPtr;
1631   ///   do {
1632   ///        unsigned long counter = 0;
1633   ///        do {
1634   ///             if (startMutations != *enumState.mutationsPtr)
1635   ///               objc_enumerationMutation(l_collection);
1636   ///             elem = (type)enumState.itemsPtr[counter++];
1637   buf += "if (limit) {\n\t";
1638   buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1639   buf += "do {\n\t\t";
1640   buf += "unsigned long counter = 0;\n\t\t";
1641   buf += "do {\n\t\t\t";
1642   buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1643   buf += "objc_enumerationMutation(l_collection);\n\t\t\t";
1644   buf += elementName;
1645   buf += " = (";
1646   buf += elementTypeAsString;
1647   buf += ")enumState.itemsPtr[counter++];";
1648   // Replace ')' in for '(' type elem in collection ')' with all of these.
1649   ReplaceText(lparenLoc, 1, buf);
1650
1651   ///            __continue_label: ;
1652   ///        } while (counter < limit);
1653   ///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
1654   ///                                  objects:items count:16]);
1655   ///   elem = nil;
1656   ///   __break_label: ;
1657   ///  }
1658   ///  else
1659   ///       elem = nil;
1660   ///  }
1661   ///
1662   buf = ";\n\t";
1663   buf += "__continue_label_";
1664   buf += utostr(ObjCBcLabelNo.back());
1665   buf += ": ;";
1666   buf += "\n\t\t";
1667   buf += "} while (counter < limit);\n\t";
1668   buf += "} while (limit = ";
1669   SynthCountByEnumWithState(buf);
1670   buf += ");\n\t";
1671   buf += elementName;
1672   buf += " = ((";
1673   buf += elementTypeAsString;
1674   buf += ")0);\n\t";
1675   buf += "__break_label_";
1676   buf += utostr(ObjCBcLabelNo.back());
1677   buf += ": ;\n\t";
1678   buf += "}\n\t";
1679   buf += "else\n\t\t";
1680   buf += elementName;
1681   buf += " = ((";
1682   buf += elementTypeAsString;
1683   buf += ")0);\n\t";
1684   buf += "}\n";
1685
1686   // Insert all these *after* the statement body.
1687   // FIXME: If this should support Obj-C++, support CXXTryStmt
1688   if (isa<CompoundStmt>(S->getBody())) {
1689     SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(1);
1690     InsertText(endBodyLoc, buf);
1691   } else {
1692     /* Need to treat single statements specially. For example:
1693      *
1694      *     for (A *a in b) if (stuff()) break;
1695      *     for (A *a in b) xxxyy;
1696      *
1697      * The following code simply scans ahead to the semi to find the actual end.
1698      */
1699     const char *stmtBuf = SM->getCharacterData(OrigEnd);
1700     const char *semiBuf = strchr(stmtBuf, ';');
1701     assert(semiBuf && "Can't find ';'");
1702     SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(semiBuf-stmtBuf+1);
1703     InsertText(endBodyLoc, buf);
1704   }
1705   Stmts.pop_back();
1706   ObjCBcLabelNo.pop_back();
1707   return 0;
1708 }
1709
1710 /// RewriteObjCSynchronizedStmt -
1711 /// This routine rewrites @synchronized(expr) stmt;
1712 /// into:
1713 /// objc_sync_enter(expr);
1714 /// @try stmt @finally { objc_sync_exit(expr); }
1715 ///
1716 Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
1717   // Get the start location and compute the semi location.
1718   SourceLocation startLoc = S->getLocStart();
1719   const char *startBuf = SM->getCharacterData(startLoc);
1720
1721   assert((*startBuf == '@') && "bogus @synchronized location");
1722
1723   std::string buf;
1724   buf = "objc_sync_enter((id)";
1725   const char *lparenBuf = startBuf;
1726   while (*lparenBuf != '(') lparenBuf++;
1727   ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1728   // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
1729   // the sync expression is typically a message expression that's already
1730   // been rewritten! (which implies the SourceLocation's are invalid).
1731   SourceLocation endLoc = S->getSynchBody()->getLocStart();
1732   const char *endBuf = SM->getCharacterData(endLoc);
1733   while (*endBuf != ')') endBuf--;
1734   SourceLocation rparenLoc = startLoc.getFileLocWithOffset(endBuf-startBuf);
1735   buf = ");\n";
1736   // declare a new scope with two variables, _stack and _rethrow.
1737   buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n";
1738   buf += "int buf[18/*32-bit i386*/];\n";
1739   buf += "char *pointers[4];} _stack;\n";
1740   buf += "id volatile _rethrow = 0;\n";
1741   buf += "objc_exception_try_enter(&_stack);\n";
1742   buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
1743   ReplaceText(rparenLoc, 1, buf);
1744   startLoc = S->getSynchBody()->getLocEnd();
1745   startBuf = SM->getCharacterData(startLoc);
1746
1747   assert((*startBuf == '}') && "bogus @synchronized block");
1748   SourceLocation lastCurlyLoc = startLoc;
1749   buf = "}\nelse {\n";
1750   buf += "  _rethrow = objc_exception_extract(&_stack);\n";
1751   buf += "}\n";
1752   buf += "{ /* implicit finally clause */\n";
1753   buf += "  if (!_rethrow) objc_exception_try_exit(&_stack);\n";
1754   
1755   std::string syncBuf;
1756   syncBuf += " objc_sync_exit(";
1757   Expr *syncExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
1758                                             CastExpr::CK_Unknown,
1759                                             S->getSynchExpr());
1760   std::string syncExprBufS;
1761   llvm::raw_string_ostream syncExprBuf(syncExprBufS);
1762   syncExpr->printPretty(syncExprBuf, *Context, 0,
1763                         PrintingPolicy(LangOpts));
1764   syncBuf += syncExprBuf.str();
1765   syncBuf += ");";
1766   
1767   buf += syncBuf;
1768   buf += "\n  if (_rethrow) objc_exception_throw(_rethrow);\n";
1769   buf += "}\n";
1770   buf += "}";
1771
1772   ReplaceText(lastCurlyLoc, 1, buf);
1773
1774   bool hasReturns = false;
1775   HasReturnStmts(S->getSynchBody(), hasReturns);
1776   if (hasReturns)
1777     RewriteSyncReturnStmts(S->getSynchBody(), syncBuf);
1778
1779   return 0;
1780 }
1781
1782 void RewriteObjC::WarnAboutReturnGotoStmts(Stmt *S)
1783 {
1784   // Perform a bottom up traversal of all children.
1785   for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
1786        CI != E; ++CI)
1787     if (*CI)
1788       WarnAboutReturnGotoStmts(*CI);
1789
1790   if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1791     Diags.Report(Context->getFullLoc(S->getLocStart()),
1792                  TryFinallyContainsReturnDiag);
1793   }
1794   return;
1795 }
1796
1797 void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns) 
1798 {  
1799   // Perform a bottom up traversal of all children.
1800   for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
1801         CI != E; ++CI)
1802    if (*CI)
1803      HasReturnStmts(*CI, hasReturns);
1804
1805  if (isa<ReturnStmt>(S))
1806    hasReturns = true;
1807  return;
1808 }
1809
1810 void RewriteObjC::RewriteTryReturnStmts(Stmt *S) {
1811  // Perform a bottom up traversal of all children.
1812  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
1813       CI != E; ++CI)
1814    if (*CI) {
1815      RewriteTryReturnStmts(*CI);
1816    }
1817  if (isa<ReturnStmt>(S)) {
1818    SourceLocation startLoc = S->getLocStart();
1819    const char *startBuf = SM->getCharacterData(startLoc);
1820
1821    const char *semiBuf = strchr(startBuf, ';');
1822    assert((*semiBuf == ';') && "RewriteTryReturnStmts: can't find ';'");
1823    SourceLocation onePastSemiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf+1);
1824
1825    std::string buf;
1826    buf = "{ objc_exception_try_exit(&_stack); return";
1827    
1828    ReplaceText(startLoc, 6, buf);
1829    InsertText(onePastSemiLoc, "}");
1830  }
1831  return;
1832 }
1833
1834 void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) {
1835   // Perform a bottom up traversal of all children.
1836   for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
1837        CI != E; ++CI)
1838     if (*CI) {
1839       RewriteSyncReturnStmts(*CI, syncExitBuf);
1840     }
1841   if (isa<ReturnStmt>(S)) {
1842     SourceLocation startLoc = S->getLocStart();
1843     const char *startBuf = SM->getCharacterData(startLoc);
1844
1845     const char *semiBuf = strchr(startBuf, ';');
1846     assert((*semiBuf == ';') && "RewriteSyncReturnStmts: can't find ';'");
1847     SourceLocation onePastSemiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf+1);
1848
1849     std::string buf;
1850     buf = "{ objc_exception_try_exit(&_stack);";
1851     buf += syncExitBuf;
1852     buf += " return";
1853     
1854     ReplaceText(startLoc, 6, buf);
1855     InsertText(onePastSemiLoc, "}");
1856   }
1857   return;
1858 }
1859
1860 Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
1861   // Get the start location and compute the semi location.
1862   SourceLocation startLoc = S->getLocStart();
1863   const char *startBuf = SM->getCharacterData(startLoc);
1864
1865   assert((*startBuf == '@') && "bogus @try location");
1866
1867   std::string buf;
1868   // declare a new scope with two variables, _stack and _rethrow.
1869   buf = "/* @try scope begin */ { struct _objc_exception_data {\n";
1870   buf += "int buf[18/*32-bit i386*/];\n";
1871   buf += "char *pointers[4];} _stack;\n";
1872   buf += "id volatile _rethrow = 0;\n";
1873   buf += "objc_exception_try_enter(&_stack);\n";
1874   buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
1875
1876   ReplaceText(startLoc, 4, buf);
1877
1878   startLoc = S->getTryBody()->getLocEnd();
1879   startBuf = SM->getCharacterData(startLoc);
1880
1881   assert((*startBuf == '}') && "bogus @try block");
1882
1883   SourceLocation lastCurlyLoc = startLoc;
1884   if (S->getNumCatchStmts()) {
1885     startLoc = startLoc.getFileLocWithOffset(1);
1886     buf = " /* @catch begin */ else {\n";
1887     buf += " id _caught = objc_exception_extract(&_stack);\n";
1888     buf += " objc_exception_try_enter (&_stack);\n";
1889     buf += " if (_setjmp(_stack.buf))\n";
1890     buf += "   _rethrow = objc_exception_extract(&_stack);\n";
1891     buf += " else { /* @catch continue */";
1892
1893     InsertText(startLoc, buf);
1894   } else { /* no catch list */
1895     buf = "}\nelse {\n";
1896     buf += "  _rethrow = objc_exception_extract(&_stack);\n";
1897     buf += "}";
1898     ReplaceText(lastCurlyLoc, 1, buf);
1899   }
1900   bool sawIdTypedCatch = false;
1901   Stmt *lastCatchBody = 0;
1902   for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
1903     ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
1904     VarDecl *catchDecl = Catch->getCatchParamDecl();
1905
1906     if (I == 0)
1907       buf = "if ("; // we are generating code for the first catch clause
1908     else
1909       buf = "else if (";
1910     startLoc = Catch->getLocStart();
1911     startBuf = SM->getCharacterData(startLoc);
1912
1913     assert((*startBuf == '@') && "bogus @catch location");
1914
1915     const char *lParenLoc = strchr(startBuf, '(');
1916
1917     if (Catch->hasEllipsis()) {
1918       // Now rewrite the body...
1919       lastCatchBody = Catch->getCatchBody();
1920       SourceLocation bodyLoc = lastCatchBody->getLocStart();
1921       const char *bodyBuf = SM->getCharacterData(bodyLoc);
1922       assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' &&
1923              "bogus @catch paren location");
1924       assert((*bodyBuf == '{') && "bogus @catch body location");
1925
1926       buf += "1) { id _tmp = _caught;";
1927       Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, buf);
1928     } else if (catchDecl) {
1929       QualType t = catchDecl->getType();
1930       if (t == Context->getObjCIdType()) {
1931         buf += "1) { ";
1932         ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
1933         sawIdTypedCatch = true;
1934       } else if (const ObjCObjectPointerType *Ptr =
1935                    t->getAs<ObjCObjectPointerType>()) {
1936         // Should be a pointer to a class.
1937         ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
1938         if (IDecl) {
1939           buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
1940           buf += IDecl->getNameAsString();
1941           buf += "\"), (struct objc_object *)_caught)) { ";
1942           ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
1943         }
1944       }
1945       // Now rewrite the body...
1946       lastCatchBody = Catch->getCatchBody();
1947       SourceLocation rParenLoc = Catch->getRParenLoc();
1948       SourceLocation bodyLoc = lastCatchBody->getLocStart();
1949       const char *bodyBuf = SM->getCharacterData(bodyLoc);
1950       const char *rParenBuf = SM->getCharacterData(rParenLoc);
1951       assert((*rParenBuf == ')') && "bogus @catch paren location");
1952       assert((*bodyBuf == '{') && "bogus @catch body location");
1953
1954       // Here we replace ") {" with "= _caught;" (which initializes and
1955       // declares the @catch parameter).
1956       ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;");
1957     } else {
1958       assert(false && "@catch rewrite bug");
1959     }
1960   }
1961   // Complete the catch list...
1962   if (lastCatchBody) {
1963     SourceLocation bodyLoc = lastCatchBody->getLocEnd();
1964     assert(*SM->getCharacterData(bodyLoc) == '}' &&
1965            "bogus @catch body location");
1966
1967     // Insert the last (implicit) else clause *before* the right curly brace.
1968     bodyLoc = bodyLoc.getFileLocWithOffset(-1);
1969     buf = "} /* last catch end */\n";
1970     buf += "else {\n";
1971     buf += " _rethrow = _caught;\n";
1972     buf += " objc_exception_try_exit(&_stack);\n";
1973     buf += "} } /* @catch end */\n";
1974     if (!S->getFinallyStmt())
1975       buf += "}\n";
1976     InsertText(bodyLoc, buf);
1977
1978     // Set lastCurlyLoc
1979     lastCurlyLoc = lastCatchBody->getLocEnd();
1980   }
1981   if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) {
1982     startLoc = finalStmt->getLocStart();
1983     startBuf = SM->getCharacterData(startLoc);
1984     assert((*startBuf == '@') && "bogus @finally start");
1985
1986     ReplaceText(startLoc, 8, "/* @finally */");
1987
1988     Stmt *body = finalStmt->getFinallyBody();
1989     SourceLocation startLoc = body->getLocStart();
1990     SourceLocation endLoc = body->getLocEnd();
1991     assert(*SM->getCharacterData(startLoc) == '{' &&
1992            "bogus @finally body location");
1993     assert(*SM->getCharacterData(endLoc) == '}' &&
1994            "bogus @finally body location");
1995
1996     startLoc = startLoc.getFileLocWithOffset(1);
1997     InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n");
1998     endLoc = endLoc.getFileLocWithOffset(-1);
1999     InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n");
2000
2001     // Set lastCurlyLoc
2002     lastCurlyLoc = body->getLocEnd();
2003
2004     // Now check for any return/continue/go statements within the @try.
2005     WarnAboutReturnGotoStmts(S->getTryBody());
2006   } else { /* no finally clause - make sure we synthesize an implicit one */
2007     buf = "{ /* implicit finally clause */\n";
2008     buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
2009     buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
2010     buf += "}";
2011     ReplaceText(lastCurlyLoc, 1, buf);
2012     
2013     // Now check for any return/continue/go statements within the @try.
2014     // The implicit finally clause won't called if the @try contains any
2015     // jump statements.
2016     bool hasReturns = false;
2017     HasReturnStmts(S->getTryBody(), hasReturns);
2018     if (hasReturns)
2019       RewriteTryReturnStmts(S->getTryBody());
2020   }
2021   // Now emit the final closing curly brace...
2022   lastCurlyLoc = lastCurlyLoc.getFileLocWithOffset(1);
2023   InsertText(lastCurlyLoc, " } /* @try scope end */\n");
2024   return 0;
2025 }
2026
2027 Stmt *RewriteObjC::RewriteObjCCatchStmt(ObjCAtCatchStmt *S) {
2028   return 0;
2029 }
2030
2031 Stmt *RewriteObjC::RewriteObjCFinallyStmt(ObjCAtFinallyStmt *S) {
2032   return 0;
2033 }
2034
2035 // This can't be done with ReplaceStmt(S, ThrowExpr), since
2036 // the throw expression is typically a message expression that's already
2037 // been rewritten! (which implies the SourceLocation's are invalid).
2038 Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
2039   // Get the start location and compute the semi location.
2040   SourceLocation startLoc = S->getLocStart();
2041   const char *startBuf = SM->getCharacterData(startLoc);
2042
2043   assert((*startBuf == '@') && "bogus @throw location");
2044
2045   std::string buf;
2046   /* void objc_exception_throw(id) __attribute__((noreturn)); */
2047   if (S->getThrowExpr())
2048     buf = "objc_exception_throw(";
2049   else // add an implicit argument
2050     buf = "objc_exception_throw(_caught";
2051
2052   // handle "@  throw" correctly.
2053   const char *wBuf = strchr(startBuf, 'w');
2054   assert((*wBuf == 'w') && "@throw: can't find 'w'");
2055   ReplaceText(startLoc, wBuf-startBuf+1, buf);
2056
2057   const char *semiBuf = strchr(startBuf, ';');
2058   assert((*semiBuf == ';') && "@throw: can't find ';'");
2059   SourceLocation semiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf);
2060   ReplaceText(semiLoc, 1, ");");
2061   return 0;
2062 }
2063
2064 Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
2065   // Create a new string expression.
2066   QualType StrType = Context->getPointerType(Context->CharTy);
2067   std::string StrEncoding;
2068   Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
2069   Expr *Replacement = StringLiteral::Create(*Context,StrEncoding.c_str(),
2070                                             StrEncoding.length(), false,StrType,
2071                                             SourceLocation());
2072   ReplaceStmt(Exp, Replacement);
2073
2074   // Replace this subexpr in the parent.
2075   // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
2076   return Replacement;
2077 }
2078
2079 Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
2080   if (!SelGetUidFunctionDecl)
2081     SynthSelGetUidFunctionDecl();
2082   assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
2083   // Create a call to sel_registerName("selName").
2084   llvm::SmallVector<Expr*, 8> SelExprs;
2085   QualType argType = Context->getPointerType(Context->CharTy);
2086   SelExprs.push_back(StringLiteral::Create(*Context,
2087                                        Exp->getSelector().getAsString().c_str(),
2088                                        Exp->getSelector().getAsString().size(),
2089                                        false, argType, SourceLocation()));
2090   CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2091                                                  &SelExprs[0], SelExprs.size());
2092   ReplaceStmt(Exp, SelExp);
2093   // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
2094   return SelExp;
2095 }
2096
2097 CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
2098   FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
2099                                                     SourceLocation EndLoc) {
2100   // Get the type, we will need to reference it in a couple spots.
2101   QualType msgSendType = FD->getType();
2102
2103   // Create a reference to the objc_msgSend() declaration.
2104   DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, msgSendType, SourceLocation());
2105
2106   // Now, we cast the reference to a pointer to the objc_msgSend type.
2107   QualType pToFunc = Context->getPointerType(msgSendType);
2108   ImplicitCastExpr *ICE = 
2109     new (Context) ImplicitCastExpr(pToFunc, CastExpr::CK_Unknown,
2110                                    DRE, CXXBaseSpecifierArray(),
2111                                    /*isLvalue=*/false);
2112
2113   const FunctionType *FT = msgSendType->getAs<FunctionType>();
2114
2115   CallExpr *Exp =  
2116     new (Context) CallExpr(*Context, ICE, args, nargs, 
2117                            FT->getCallResultType(*Context), EndLoc);
2118   return Exp;
2119 }
2120
2121 static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
2122                                 const char *&startRef, const char *&endRef) {
2123   while (startBuf < endBuf) {
2124     if (*startBuf == '<')
2125       startRef = startBuf; // mark the start.
2126     if (*startBuf == '>') {
2127       if (startRef && *startRef == '<') {
2128         endRef = startBuf; // mark the end.
2129         return true;
2130       }
2131       return false;
2132     }
2133     startBuf++;
2134   }
2135   return false;
2136 }
2137
2138 static void scanToNextArgument(const char *&argRef) {
2139   int angle = 0;
2140   while (*argRef != ')' && (*argRef != ',' || angle > 0)) {
2141     if (*argRef == '<')
2142       angle++;
2143     else if (*argRef == '>')
2144       angle--;
2145     argRef++;
2146   }
2147   assert(angle == 0 && "scanToNextArgument - bad protocol type syntax");
2148 }
2149
2150 bool RewriteObjC::needToScanForQualifiers(QualType T) {
2151   if (T->isObjCQualifiedIdType())
2152     return true;
2153   if (const PointerType *PT = T->getAs<PointerType>()) {
2154     if (PT->getPointeeType()->isObjCQualifiedIdType())
2155       return true;
2156   }
2157   if (T->isObjCObjectPointerType()) {
2158     T = T->getPointeeType();
2159     return T->isObjCQualifiedInterfaceType();
2160   }
2161   return false;
2162 }
2163
2164 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
2165   QualType Type = E->getType();
2166   if (needToScanForQualifiers(Type)) {
2167     SourceLocation Loc, EndLoc;
2168
2169     if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) {
2170       Loc = ECE->getLParenLoc();
2171       EndLoc = ECE->getRParenLoc();
2172     } else {
2173       Loc = E->getLocStart();
2174       EndLoc = E->getLocEnd();
2175     }
2176     // This will defend against trying to rewrite synthesized expressions.
2177     if (Loc.isInvalid() || EndLoc.isInvalid())
2178       return;
2179
2180     const char *startBuf = SM->getCharacterData(Loc);
2181     const char *endBuf = SM->getCharacterData(EndLoc);
2182     const char *startRef = 0, *endRef = 0;
2183     if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2184       // Get the locations of the startRef, endRef.
2185       SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-startBuf);
2186       SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-startBuf+1);
2187       // Comment out the protocol references.
2188       InsertText(LessLoc, "/*");
2189       InsertText(GreaterLoc, "*/");
2190     }
2191   }
2192 }
2193
2194 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
2195   SourceLocation Loc;
2196   QualType Type;
2197   const FunctionProtoType *proto = 0;
2198   if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2199     Loc = VD->getLocation();
2200     Type = VD->getType();
2201   }
2202   else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2203     Loc = FD->getLocation();
2204     // Check for ObjC 'id' and class types that have been adorned with protocol
2205     // information (id<p>, C<p>*). The protocol references need to be rewritten!
2206     const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
2207     assert(funcType && "missing function type");
2208     proto = dyn_cast<FunctionProtoType>(funcType);
2209     if (!proto)
2210       return;
2211     Type = proto->getResultType();
2212   }
2213   else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2214     Loc = FD->getLocation();
2215     Type = FD->getType();
2216   }
2217   else
2218     return;
2219
2220   if (needToScanForQualifiers(Type)) {
2221     // Since types are unique, we need to scan the buffer.
2222
2223     const char *endBuf = SM->getCharacterData(Loc);
2224     const char *startBuf = endBuf;
2225     while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart)
2226       startBuf--; // scan backward (from the decl location) for return type.
2227     const char *startRef = 0, *endRef = 0;
2228     if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2229       // Get the locations of the startRef, endRef.
2230       SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-endBuf);
2231       SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-endBuf+1);
2232       // Comment out the protocol references.
2233       InsertText(LessLoc, "/*");
2234       InsertText(GreaterLoc, "*/");
2235     }
2236   }
2237   if (!proto)
2238       return; // most likely, was a variable
2239   // Now check arguments.
2240   const char *startBuf = SM->getCharacterData(Loc);
2241   const char *startFuncBuf = startBuf;
2242   for (unsigned i = 0; i < proto->getNumArgs(); i++) {
2243     if (needToScanForQualifiers(proto->getArgType(i))) {
2244       // Since types are unique, we need to scan the buffer.
2245
2246       const char *endBuf = startBuf;
2247       // scan forward (from the decl location) for argument types.
2248       scanToNextArgument(endBuf);
2249       const char *startRef = 0, *endRef = 0;
2250       if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2251         // Get the locations of the startRef, endRef.
2252         SourceLocation LessLoc =
2253           Loc.getFileLocWithOffset(startRef-startFuncBuf);
2254         SourceLocation GreaterLoc =
2255           Loc.getFileLocWithOffset(endRef-startFuncBuf+1);
2256         // Comment out the protocol references.
2257         InsertText(LessLoc, "/*");
2258         InsertText(GreaterLoc, "*/");
2259       }
2260       startBuf = ++endBuf;
2261     }
2262     else {
2263       // If the function name is derived from a macro expansion, then the
2264       // argument buffer will not follow the name. Need to speak with Chris.
2265       while (*startBuf && *startBuf != ')' && *startBuf != ',')
2266         startBuf++; // scan forward (from the decl location) for argument types.
2267       startBuf++;
2268     }
2269   }
2270 }
2271
2272 void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) {
2273   QualType QT = ND->getType();
2274   const Type* TypePtr = QT->getAs<Type>();
2275   if (!isa<TypeOfExprType>(TypePtr))
2276     return;
2277   while (isa<TypeOfExprType>(TypePtr)) {
2278     const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2279     QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
2280     TypePtr = QT->getAs<Type>();
2281   }
2282   // FIXME. This will not work for multiple declarators; as in:
2283   // __typeof__(a) b,c,d;
2284   std::string TypeAsString(QT.getAsString(Context->PrintingPolicy));
2285   SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
2286   const char *startBuf = SM->getCharacterData(DeclLoc);
2287   if (ND->getInit()) {
2288     std::string Name(ND->getNameAsString());
2289     TypeAsString += " " + Name + " = ";
2290     Expr *E = ND->getInit();
2291     SourceLocation startLoc;
2292     if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
2293       startLoc = ECE->getLParenLoc();
2294     else
2295       startLoc = E->getLocStart();
2296     startLoc = SM->getInstantiationLoc(startLoc);
2297     const char *endBuf = SM->getCharacterData(startLoc);
2298     ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2299   }
2300   else {
2301     SourceLocation X = ND->getLocEnd();
2302     X = SM->getInstantiationLoc(X);
2303     const char *endBuf = SM->getCharacterData(X);
2304     ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2305   }
2306 }
2307
2308 // SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
2309 void RewriteObjC::SynthSelGetUidFunctionDecl() {
2310   IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
2311   llvm::SmallVector<QualType, 16> ArgTys;
2312   ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2313   QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(),
2314                                                   &ArgTys[0], ArgTys.size(),
2315                                                   false /*isVariadic*/, 0,
2316                                                   false, false, 0, 0,
2317                                                   FunctionType::ExtInfo());
2318   SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2319                                            SourceLocation(),
2320                                            SelGetUidIdent, getFuncType, 0,
2321                                            FunctionDecl::Extern,
2322                                            FunctionDecl::None, false);
2323 }
2324
2325 void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
2326   // declared in <objc/objc.h>
2327   if (FD->getIdentifier() &&
2328       strcmp(FD->getNameAsCString(), "sel_registerName") == 0) {
2329     SelGetUidFunctionDecl = FD;
2330     return;
2331   }
2332   RewriteObjCQualifiedInterfaceTypes(FD);
2333 }
2334
2335 void RewriteObjC::RewriteBlockPointerType(std::string& Str, QualType Type) {
2336   std::string TypeString(Type.getAsString(Context->PrintingPolicy));
2337   const char *argPtr = TypeString.c_str();
2338   if (!strchr(argPtr, '^')) {
2339     Str += TypeString;
2340     return;
2341   }
2342   while (*argPtr) {
2343     Str += (*argPtr == '^' ? '*' : *argPtr);
2344     argPtr++;
2345   }
2346 }
2347
2348 // FIXME. Consolidate this routine with RewriteBlockPointerType.
2349 void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2350                                                   ValueDecl *VD) {
2351   QualType Type = VD->getType();
2352   std::string TypeString(Type.getAsString(Context->PrintingPolicy));
2353   const char *argPtr = TypeString.c_str();
2354   int paren = 0;
2355   while (*argPtr) {
2356     switch (*argPtr) {
2357       case '(':
2358         Str += *argPtr;
2359         paren++;
2360         break;
2361       case ')':
2362         Str += *argPtr;
2363         paren--;
2364         break;
2365       case '^':
2366         Str += '*';
2367         if (paren == 1)
2368           Str += VD->getNameAsString();
2369         break;
2370       default:
2371         Str += *argPtr;
2372         break;
2373     }
2374     argPtr++;
2375   }
2376 }
2377
2378
2379 void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
2380   SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
2381   const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
2382   const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType);
2383   if (!proto)
2384     return;
2385   QualType Type = proto->getResultType();
2386   std::string FdStr = Type.getAsString(Context->PrintingPolicy);
2387   FdStr += " ";
2388   FdStr += FD->getNameAsCString();
2389   FdStr +=  "(";
2390   unsigned numArgs = proto->getNumArgs();
2391   for (unsigned i = 0; i < numArgs; i++) {
2392     QualType ArgType = proto->getArgType(i);
2393     RewriteBlockPointerType(FdStr, ArgType);
2394     if (i+1 < numArgs)
2395       FdStr += ", ";
2396   }
2397   FdStr +=  ");\n";
2398   InsertText(FunLocStart, FdStr);
2399   CurFunctionDeclToDeclareForBlock = 0;
2400 }
2401
2402 // SynthSuperContructorFunctionDecl - id objc_super(id obj, id super);
2403 void RewriteObjC::SynthSuperContructorFunctionDecl() {
2404   if (SuperContructorFunctionDecl)
2405     return;
2406   IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super");
2407   llvm::SmallVector<QualType, 16> ArgTys;
2408   QualType argT = Context->getObjCIdType();
2409   assert(!argT.isNull() && "Can't find 'id' type");
2410   ArgTys.push_back(argT);
2411   ArgTys.push_back(argT);
2412   QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
2413                                                   &ArgTys[0], ArgTys.size(),
2414                                                   false, 0,
2415                                                   false, false, 0, 0,
2416                                                   FunctionType::ExtInfo());
2417   SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2418                                          SourceLocation(),
2419                                          msgSendIdent, msgSendType, 0,
2420                                          FunctionDecl::Extern,
2421                                          FunctionDecl::None, false);
2422 }
2423
2424 // SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
2425 void RewriteObjC::SynthMsgSendFunctionDecl() {
2426   IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
2427   llvm::SmallVector<QualType, 16> ArgTys;
2428   QualType argT = Context->getObjCIdType();
2429   assert(!argT.isNull() && "Can't find 'id' type");
2430   ArgTys.push_back(argT);
2431   argT = Context->getObjCSelType();
2432   assert(!argT.isNull() && "Can't find 'SEL' type");
2433   ArgTys.push_back(argT);
2434   QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
2435                                                   &ArgTys[0], ArgTys.size(),
2436                                                   true /*isVariadic*/, 0,
2437                                                   false, false, 0, 0,
2438                                                   FunctionType::ExtInfo());
2439   MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2440                                          SourceLocation(),
2441                                          msgSendIdent, msgSendType, 0,
2442                                          FunctionDecl::Extern,
2443                                          FunctionDecl::None, false);
2444 }
2445
2446 // SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
2447 void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
2448   IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
2449   llvm::SmallVector<QualType, 16> ArgTys;
2450   RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
2451                                       SourceLocation(),
2452                                       &Context->Idents.get("objc_super"));
2453   QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
2454   assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
2455   ArgTys.push_back(argT);
2456   argT = Context->getObjCSelType();
2457   assert(!argT.isNull() && "Can't find 'SEL' type");
2458   ArgTys.push_back(argT);
2459   QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
2460                                                   &ArgTys[0], ArgTys.size(),
2461                                                   true /*isVariadic*/, 0,
2462                                                   false, false, 0, 0,
2463                                                   FunctionType::ExtInfo());
2464   MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2465                                               SourceLocation(),
2466                                               msgSendIdent, msgSendType, 0,
2467                                               FunctionDecl::Extern,
2468                                               FunctionDecl::None, false);
2469 }
2470
2471 // SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
2472 void RewriteObjC::SynthMsgSendStretFunctionDecl() {
2473   IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
2474   llvm::SmallVector<QualType, 16> ArgTys;
2475   QualType argT = Context->getObjCIdType();
2476   assert(!argT.isNull() && "Can't find 'id' type");
2477   ArgTys.push_back(argT);
2478   argT = Context->getObjCSelType();
2479   assert(!argT.isNull() && "Can't find 'SEL' type");
2480   ArgTys.push_back(argT);
2481   QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
2482                                                   &ArgTys[0], ArgTys.size(),
2483                                                   true /*isVariadic*/, 0,
2484                                                   false, false, 0, 0,
2485                                                   FunctionType::ExtInfo());
2486   MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2487                                          SourceLocation(),
2488                                          msgSendIdent, msgSendType, 0,
2489                                          FunctionDecl::Extern,
2490                                          FunctionDecl::None, false);
2491 }
2492
2493 // SynthMsgSendSuperStretFunctionDecl -
2494 // id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...);
2495 void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
2496   IdentifierInfo *msgSendIdent =
2497     &Context->Idents.get("objc_msgSendSuper_stret");
2498   llvm::SmallVector<QualType, 16> ArgTys;
2499   RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
2500                                       SourceLocation(),
2501                                       &Context->Idents.get("objc_super"));
2502   QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
2503   assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
2504   ArgTys.push_back(argT);
2505   argT = Context->getObjCSelType();
2506   assert(!argT.isNull() && "Can't find 'SEL' type");
2507   ArgTys.push_back(argT);
2508   QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
2509                                                   &ArgTys[0], ArgTys.size(),
2510                                                   true /*isVariadic*/, 0,
2511                                                   false, false, 0, 0,
2512                                                   FunctionType::ExtInfo());
2513   MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2514                                                        SourceLocation(),
2515                                               msgSendIdent, msgSendType, 0,
2516                                               FunctionDecl::Extern,
2517                                               FunctionDecl::None, false);
2518 }
2519
2520 // SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
2521 void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
2522   IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
2523   llvm::SmallVector<QualType, 16> ArgTys;
2524   QualType argT = Context->getObjCIdType();
2525   assert(!argT.isNull() && "Can't find 'id' type");
2526   ArgTys.push_back(argT);
2527   argT = Context->getObjCSelType();
2528   assert(!argT.isNull() && "Can't find 'SEL' type");
2529   ArgTys.push_back(argT);
2530   QualType msgSendType = Context->getFunctionType(Context->DoubleTy,
2531                                                   &ArgTys[0], ArgTys.size(),
2532                                                   true /*isVariadic*/, 0,
2533                                                   false, false, 0, 0,
2534                                                   FunctionType::ExtInfo());
2535   MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2536                                               SourceLocation(),
2537                                               msgSendIdent, msgSendType, 0,
2538                                               FunctionDecl::Extern,
2539                                               FunctionDecl::None, false);
2540 }
2541
2542 // SynthGetClassFunctionDecl - id objc_getClass(const char *name);
2543 void RewriteObjC::SynthGetClassFunctionDecl() {
2544   IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
2545   llvm::SmallVector<QualType, 16> ArgTys;
2546   ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2547   QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
2548                                                    &ArgTys[0], ArgTys.size(),
2549                                                    false /*isVariadic*/, 0,
2550                                                   false, false, 0, 0,
2551                                                    FunctionType::ExtInfo());
2552   GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2553                                           SourceLocation(),
2554                                           getClassIdent, getClassType, 0,
2555                                           FunctionDecl::Extern,
2556                                           FunctionDecl::None, false);
2557 }
2558
2559 // SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
2560 void RewriteObjC::SynthGetSuperClassFunctionDecl() {
2561   IdentifierInfo *getSuperClassIdent = 
2562     &Context->Idents.get("class_getSuperclass");
2563   llvm::SmallVector<QualType, 16> ArgTys;
2564   ArgTys.push_back(Context->getObjCClassType());
2565   QualType getClassType = Context->getFunctionType(Context->getObjCClassType(),
2566                                                    &ArgTys[0], ArgTys.size(),
2567                                                    false /*isVariadic*/, 0,
2568                                                    false, false, 0, 0,
2569                                                    FunctionType::ExtInfo());
2570   GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2571                                                    SourceLocation(),
2572                                                    getSuperClassIdent,
2573                                                    getClassType, 0,
2574                                                    FunctionDecl::Extern,
2575                                                    FunctionDecl::None,
2576                                                    false);
2577 }
2578
2579 // SynthGetMetaClassFunctionDecl - id objc_getClass(const char *name);
2580 void RewriteObjC::SynthGetMetaClassFunctionDecl() {
2581   IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
2582   llvm::SmallVector<QualType, 16> ArgTys;
2583   ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2584   QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
2585                                                    &ArgTys[0], ArgTys.size(),
2586                                                    false /*isVariadic*/, 0,
2587                                                    false, false, 0, 0,
2588                                                    FunctionType::ExtInfo());
2589   GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2590                                               SourceLocation(),
2591                                               getClassIdent, getClassType, 0,
2592                                               FunctionDecl::Extern,
2593                                               FunctionDecl::None, false);
2594 }
2595
2596 Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
2597   QualType strType = getConstantStringStructType();
2598
2599   std::string S = "__NSConstantStringImpl_";
2600
2601   std::string tmpName = InFileName;
2602   unsigned i;
2603   for (i=0; i < tmpName.length(); i++) {
2604     char c = tmpName.at(i);
2605     // replace any non alphanumeric characters with '_'.
2606     if (!isalpha(c) && (c < '0' || c > '9'))
2607       tmpName[i] = '_';
2608   }
2609   S += tmpName;
2610   S += "_";
2611   S += utostr(NumObjCStringLiterals++);
2612
2613   Preamble += "static __NSConstantStringImpl " + S;
2614   Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2615   Preamble += "0x000007c8,"; // utf8_str
2616   // The pretty printer for StringLiteral handles escape characters properly.
2617   std::string prettyBufS;
2618   llvm::raw_string_ostream prettyBuf(prettyBufS);
2619   Exp->getString()->printPretty(prettyBuf, *Context, 0,
2620                                 PrintingPolicy(LangOpts));
2621   Preamble += prettyBuf.str();
2622   Preamble += ",";
2623   Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
2624
2625   VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
2626                                     &Context->Idents.get(S), strType, 0,
2627                                     VarDecl::Static, VarDecl::None);
2628   DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, SourceLocation());
2629   Expr *Unop = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
2630                                  Context->getPointerType(DRE->getType()),
2631                                  SourceLocation());
2632   // cast to NSConstantString *
2633   CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
2634                                             CastExpr::CK_Unknown, Unop);
2635   ReplaceStmt(Exp, cast);
2636   // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
2637   return cast;
2638 }
2639
2640 bool RewriteObjC::isSuperReceiver(Expr *recExpr) {
2641   // check if we are sending a message to 'super'
2642   if (!CurMethodDef || !CurMethodDef->isInstanceMethod()) return false;
2643   return isa<ObjCSuperExpr>(recExpr);
2644 }
2645
2646 // struct objc_super { struct objc_object *receiver; struct objc_class *super; };
2647 QualType RewriteObjC::getSuperStructType() {
2648   if (!SuperStructDecl) {
2649     SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
2650                                          SourceLocation(),
2651                                          &Context->Idents.get("objc_super"));
2652     QualType FieldTypes[2];
2653
2654     // struct objc_object *receiver;
2655     FieldTypes[0] = Context->getObjCIdType();
2656     // struct objc_class *super;
2657     FieldTypes[1] = Context->getObjCClassType();
2658
2659     // Create fields
2660     for (unsigned i = 0; i < 2; ++i) {
2661       SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
2662                                                  SourceLocation(), 0,
2663                                                  FieldTypes[i], 0,
2664                                                  /*BitWidth=*/0,
2665                                                  /*Mutable=*/false));
2666     }
2667
2668     SuperStructDecl->completeDefinition();
2669   }
2670   return Context->getTagDeclType(SuperStructDecl);
2671 }
2672
2673 QualType RewriteObjC::getConstantStringStructType() {
2674   if (!ConstantStringDecl) {
2675     ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
2676                                             SourceLocation(),
2677                          &Context->Idents.get("__NSConstantStringImpl"));
2678     QualType FieldTypes[4];
2679
2680     // struct objc_object *receiver;
2681     FieldTypes[0] = Context->getObjCIdType();
2682     // int flags;
2683     FieldTypes[1] = Context->IntTy;
2684     // char *str;
2685     FieldTypes[2] = Context->getPointerType(Context->CharTy);
2686     // long length;
2687     FieldTypes[3] = Context->LongTy;
2688
2689     // Create fields
2690     for (unsigned i = 0; i < 4; ++i) {
2691       ConstantStringDecl->addDecl(FieldDecl::Create(*Context,
2692                                                     ConstantStringDecl,
2693                                                     SourceLocation(), 0,
2694                                                     FieldTypes[i], 0,
2695                                                     /*BitWidth=*/0,
2696                                                     /*Mutable=*/true));
2697     }
2698
2699     ConstantStringDecl->completeDefinition();
2700   }
2701   return Context->getTagDeclType(ConstantStringDecl);
2702 }
2703
2704 Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
2705                                     SourceLocation StartLoc,
2706                                     SourceLocation EndLoc) {
2707   if (!SelGetUidFunctionDecl)
2708     SynthSelGetUidFunctionDecl();
2709   if (!MsgSendFunctionDecl)
2710     SynthMsgSendFunctionDecl();
2711   if (!MsgSendSuperFunctionDecl)
2712     SynthMsgSendSuperFunctionDecl();
2713   if (!MsgSendStretFunctionDecl)
2714     SynthMsgSendStretFunctionDecl();
2715   if (!MsgSendSuperStretFunctionDecl)
2716     SynthMsgSendSuperStretFunctionDecl();
2717   if (!MsgSendFpretFunctionDecl)
2718     SynthMsgSendFpretFunctionDecl();
2719   if (!GetClassFunctionDecl)
2720     SynthGetClassFunctionDecl();
2721   if (!GetSuperClassFunctionDecl)
2722     SynthGetSuperClassFunctionDecl();
2723   if (!GetMetaClassFunctionDecl)
2724     SynthGetMetaClassFunctionDecl();
2725
2726   // default to objc_msgSend().
2727   FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
2728   // May need to use objc_msgSend_stret() as well.
2729   FunctionDecl *MsgSendStretFlavor = 0;
2730   if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
2731     QualType resultType = mDecl->getResultType();
2732     if (resultType->isRecordType())
2733       MsgSendStretFlavor = MsgSendStretFunctionDecl;
2734     else if (resultType->isRealFloatingType())
2735       MsgSendFlavor = MsgSendFpretFunctionDecl;
2736   }
2737
2738   // Synthesize a call to objc_msgSend().
2739   llvm::SmallVector<Expr*, 8> MsgExprs;
2740   switch (Exp->getReceiverKind()) {
2741   case ObjCMessageExpr::SuperClass: {
2742     MsgSendFlavor = MsgSendSuperFunctionDecl;
2743     if (MsgSendStretFlavor)
2744       MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
2745     assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
2746
2747     ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
2748
2749     llvm::SmallVector<Expr*, 4> InitExprs;
2750
2751     // set the receiver to self, the first argument to all methods.
2752     InitExprs.push_back(
2753       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
2754                                CastExpr::CK_Unknown,
2755                    new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
2756                                    Context->getObjCIdType(),
2757                                    SourceLocation()))
2758                         ); // set the 'receiver'.
2759
2760     // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2761     llvm::SmallVector<Expr*, 8> ClsExprs;
2762     QualType argType = Context->getPointerType(Context->CharTy);
2763     ClsExprs.push_back(StringLiteral::Create(*Context,
2764                                    ClassDecl->getIdentifier()->getNameStart(),
2765                                    ClassDecl->getIdentifier()->getLength(),
2766                                    false, argType, SourceLocation()));
2767     CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
2768                                                  &ClsExprs[0],
2769                                                  ClsExprs.size(),
2770                                                  StartLoc,
2771                                                  EndLoc);
2772     // (Class)objc_getClass("CurrentClass")
2773     CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
2774                                              Context->getObjCClassType(),
2775                                              CastExpr::CK_Unknown, Cls);
2776     ClsExprs.clear();
2777     ClsExprs.push_back(ArgExpr);
2778     Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
2779                                        &ClsExprs[0], ClsExprs.size(),
2780                                        StartLoc, EndLoc);
2781     
2782     // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2783     // To turn off a warning, type-cast to 'id'
2784     InitExprs.push_back( // set 'super class', using class_getSuperclass().
2785                         NoTypeInfoCStyleCastExpr(Context,
2786                                                  Context->getObjCIdType(),
2787                                                  CastExpr::CK_Unknown, Cls));
2788     // struct objc_super
2789     QualType superType = getSuperStructType();
2790     Expr *SuperRep;
2791
2792     if (LangOpts.Microsoft) {
2793       SynthSuperContructorFunctionDecl();
2794       // Simulate a contructor call...
2795       DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
2796                                          superType, SourceLocation());
2797       SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
2798                                         InitExprs.size(),
2799                                         superType, SourceLocation());
2800       // The code for super is a little tricky to prevent collision with
2801       // the structure definition in the header. The rewriter has it's own
2802       // internal definition (__rw_objc_super) that is uses. This is why
2803       // we need the cast below. For example:
2804       // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
2805       //
2806       SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
2807                                Context->getPointerType(SuperRep->getType()),
2808                                SourceLocation());
2809       SuperRep = NoTypeInfoCStyleCastExpr(Context,
2810                                           Context->getPointerType(superType),
2811                                           CastExpr::CK_Unknown, SuperRep);
2812     } else {
2813       // (struct objc_super) { <exprs from above> }
2814       InitListExpr *ILE =
2815         new (Context) InitListExpr(*Context, SourceLocation(),
2816                                    &InitExprs[0], InitExprs.size(),
2817                                    SourceLocation());
2818       TypeSourceInfo *superTInfo
2819         = Context->getTrivialTypeSourceInfo(superType);
2820       SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
2821                                                    superType, ILE, false);
2822       // struct objc_super *
2823       SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
2824                                Context->getPointerType(SuperRep->getType()),
2825                                SourceLocation());
2826     }
2827     MsgExprs.push_back(SuperRep);
2828     break;
2829   }
2830
2831   case ObjCMessageExpr::Class: {
2832     llvm::SmallVector<Expr*, 8> ClsExprs;
2833     QualType argType = Context->getPointerType(Context->CharTy);
2834     ObjCInterfaceDecl *Class
2835       = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
2836     IdentifierInfo *clsName = Class->getIdentifier();
2837     ClsExprs.push_back(StringLiteral::Create(*Context,
2838                                              clsName->getNameStart(),
2839                                              clsName->getLength(),
2840                                              false, argType,
2841                                              SourceLocation()));
2842     CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
2843                                                  &ClsExprs[0],
2844                                                  ClsExprs.size(), 
2845                                                  StartLoc, EndLoc);
2846     MsgExprs.push_back(Cls);
2847     break;
2848   }
2849
2850   case ObjCMessageExpr::SuperInstance:{
2851     MsgSendFlavor = MsgSendSuperFunctionDecl;
2852     if (MsgSendStretFlavor)
2853       MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
2854     assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
2855     ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
2856     llvm::SmallVector<Expr*, 4> InitExprs;
2857
2858     InitExprs.push_back(
2859       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
2860                                CastExpr::CK_Unknown,
2861                    new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
2862                                    Context->getObjCIdType(),
2863                                    SourceLocation()))
2864                         ); // set the 'receiver'.
2865     
2866     // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2867     llvm::SmallVector<Expr*, 8> ClsExprs;
2868     QualType argType = Context->getPointerType(Context->CharTy);
2869     ClsExprs.push_back(StringLiteral::Create(*Context,
2870                                    ClassDecl->getIdentifier()->getNameStart(),
2871                                    ClassDecl->getIdentifier()->getLength(),
2872                                    false, argType, SourceLocation()));
2873     CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
2874                                                  &ClsExprs[0],
2875                                                  ClsExprs.size(), 
2876                                                  StartLoc, EndLoc);
2877     // (Class)objc_getClass("CurrentClass")
2878     CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
2879                                                  Context->getObjCClassType(),
2880                                                  CastExpr::CK_Unknown, Cls);
2881     ClsExprs.clear();
2882     ClsExprs.push_back(ArgExpr);
2883     Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
2884                                        &ClsExprs[0], ClsExprs.size(),
2885                                        StartLoc, EndLoc);
2886     
2887     // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2888     // To turn off a warning, type-cast to 'id'
2889     InitExprs.push_back(
2890       // set 'super class', using class_getSuperclass().
2891       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
2892                                CastExpr::CK_Unknown, Cls));
2893     // struct objc_super
2894     QualType superType = getSuperStructType();
2895     Expr *SuperRep;
2896
2897     if (LangOpts.Microsoft) {
2898       SynthSuperContructorFunctionDecl();
2899       // Simulate a contructor call...
2900       DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
2901                                          superType, SourceLocation());
2902       SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
2903                                         InitExprs.size(),
2904                                         superType, SourceLocation());
2905       // The code for super is a little tricky to prevent collision with
2906       // the structure definition in the header. The rewriter has it's own
2907       // internal definition (__rw_objc_super) that is uses. This is why
2908       // we need the cast below. For example:
2909       // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
2910       //
2911       SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
2912                                Context->getPointerType(SuperRep->getType()),
2913                                SourceLocation());
2914       SuperRep = NoTypeInfoCStyleCastExpr(Context,
2915                                Context->getPointerType(superType),
2916                                CastExpr::CK_Unknown, SuperRep);
2917     } else {
2918       // (struct objc_super) { <exprs from above> }
2919       InitListExpr *ILE =
2920         new (Context) InitListExpr(*Context, SourceLocation(),
2921                                    &InitExprs[0], InitExprs.size(),
2922                                    SourceLocation());
2923       TypeSourceInfo *superTInfo
2924         = Context->getTrivialTypeSourceInfo(superType);
2925       SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
2926                                                    superType, ILE, false);
2927     }
2928     MsgExprs.push_back(SuperRep);
2929     break;
2930   }
2931
2932   case ObjCMessageExpr::Instance: {
2933     // Remove all type-casts because it may contain objc-style types; e.g.
2934     // Foo<Proto> *.
2935     Expr *recExpr = Exp->getInstanceReceiver();
2936     while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
2937       recExpr = CE->getSubExpr();
2938     recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
2939                                        CastExpr::CK_Unknown, recExpr);
2940     MsgExprs.push_back(recExpr);
2941     break;
2942   }
2943   }
2944
2945   // Create a call to sel_registerName("selName"), it will be the 2nd argument.
2946   llvm::SmallVector<Expr*, 8> SelExprs;
2947   QualType argType = Context->getPointerType(Context->CharTy);
2948   SelExprs.push_back(StringLiteral::Create(*Context,
2949                                        Exp->getSelector().getAsString().c_str(),
2950                                        Exp->getSelector().getAsString().size(),
2951                                        false, argType, SourceLocation()));
2952   CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2953                                                  &SelExprs[0], SelExprs.size(),
2954                                                   StartLoc,
2955                                                   EndLoc);
2956   MsgExprs.push_back(SelExp);
2957
2958   // Now push any user supplied arguments.
2959   for (unsigned i = 0; i < Exp->getNumArgs(); i++) {
2960     Expr *userExpr = Exp->getArg(i);
2961     // Make all implicit casts explicit...ICE comes in handy:-)
2962     if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
2963       // Reuse the ICE type, it is exactly what the doctor ordered.
2964       QualType type = ICE->getType()->isObjCQualifiedIdType()
2965                                 ? Context->getObjCIdType()
2966                                 : ICE->getType();
2967       // Make sure we convert "type (^)(...)" to "type (*)(...)".
2968       (void)convertBlockPointerToFunctionPointer(type);
2969       userExpr = NoTypeInfoCStyleCastExpr(Context, type, CastExpr::CK_Unknown,
2970                                           userExpr);
2971     }
2972     // Make id<P...> cast into an 'id' cast.
2973     else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
2974       if (CE->getType()->isObjCQualifiedIdType()) {
2975         while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
2976           userExpr = CE->getSubExpr();
2977         userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
2978                                             CastExpr::CK_Unknown, userExpr);
2979       }
2980     }
2981     MsgExprs.push_back(userExpr);
2982     // We've transferred the ownership to MsgExprs. For now, we *don't* null
2983     // out the argument in the original expression (since we aren't deleting
2984     // the ObjCMessageExpr). See RewritePropertySetter() usage for more info.
2985     //Exp->setArg(i, 0);
2986   }
2987   // Generate the funky cast.
2988   CastExpr *cast;
2989   llvm::SmallVector<QualType, 8> ArgTypes;
2990   QualType returnType;
2991
2992   // Push 'id' and 'SEL', the 2 implicit arguments.
2993   if (MsgSendFlavor == MsgSendSuperFunctionDecl)
2994     ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
2995   else
2996     ArgTypes.push_back(Context->getObjCIdType());
2997   ArgTypes.push_back(Context->getObjCSelType());
2998   if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) {
2999     // Push any user argument types.
3000     for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
3001          E = OMD->param_end(); PI != E; ++PI) {
3002       QualType t = (*PI)->getType()->isObjCQualifiedIdType()
3003                      ? Context->getObjCIdType()
3004                      : (*PI)->getType();
3005       // Make sure we convert "t (^)(...)" to "t (*)(...)".
3006       (void)convertBlockPointerToFunctionPointer(t);
3007       ArgTypes.push_back(t);
3008     }
3009     returnType = OMD->getResultType()->isObjCQualifiedIdType()
3010                    ? Context->getObjCIdType() : OMD->getResultType();
3011     (void)convertBlockPointerToFunctionPointer(returnType);
3012   } else {
3013     returnType = Context->getObjCIdType();
3014   }
3015   // Get the type, we will need to reference it in a couple spots.
3016   QualType msgSendType = MsgSendFlavor->getType();
3017
3018   // Create a reference to the objc_msgSend() declaration.
3019   DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType,
3020                                      SourceLocation());
3021
3022   // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
3023   // If we don't do this cast, we get the following bizarre warning/note:
3024   // xx.m:13: warning: function called through a non-compatible type
3025   // xx.m:13: note: if this code is reached, the program will abort
3026   cast = NoTypeInfoCStyleCastExpr(Context,
3027                                   Context->getPointerType(Context->VoidTy),
3028                                   CastExpr::CK_Unknown, DRE);
3029
3030   // Now do the "normal" pointer to function cast.
3031   QualType castType = Context->getFunctionType(returnType,
3032     &ArgTypes[0], ArgTypes.size(),
3033     // If we don't have a method decl, force a variadic cast.
3034     Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true, 0,
3035                                                false, false, 0, 0,
3036                                                FunctionType::ExtInfo());
3037   castType = Context->getPointerType(castType);
3038   cast = NoTypeInfoCStyleCastExpr(Context, castType, CastExpr::CK_Unknown,
3039                                   cast);
3040
3041   // Don't forget the parens to enforce the proper binding.
3042   ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
3043
3044   const FunctionType *FT = msgSendType->getAs<FunctionType>();
3045   CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
3046                                         MsgExprs.size(),
3047                                         FT->getResultType(), EndLoc);
3048   Stmt *ReplacingStmt = CE;
3049   if (MsgSendStretFlavor) {
3050     // We have the method which returns a struct/union. Must also generate
3051     // call to objc_msgSend_stret and hang both varieties on a conditional
3052     // expression which dictate which one to envoke depending on size of
3053     // method's return type.
3054
3055     // Create a reference to the objc_msgSend_stret() declaration.
3056     DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, msgSendType,
3057                                          SourceLocation());
3058     // Need to cast objc_msgSend_stret to "void *" (see above comment).
3059     cast = NoTypeInfoCStyleCastExpr(Context,
3060                                     Context->getPointerType(Context->VoidTy),
3061                                     CastExpr::CK_Unknown, STDRE);
3062     // Now do the "normal" pointer to function cast.
3063     castType = Context->getFunctionType(returnType,
3064       &ArgTypes[0], ArgTypes.size(),
3065       Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false, 0,
3066                                         false, false, 0, 0,
3067                                         FunctionType::ExtInfo());
3068     castType = Context->getPointerType(castType);
3069     cast = NoTypeInfoCStyleCastExpr(Context, castType, CastExpr::CK_Unknown,
3070                                     cast);
3071
3072     // Don't forget the parens to enforce the proper binding.
3073     PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast);
3074
3075     FT = msgSendType->getAs<FunctionType>();
3076     CallExpr *STCE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
3077                                             MsgExprs.size(),
3078                                             FT->getResultType(), SourceLocation());
3079
3080     // Build sizeof(returnType)
3081     SizeOfAlignOfExpr *sizeofExpr = new (Context) SizeOfAlignOfExpr(true,
3082                             Context->getTrivialTypeSourceInfo(returnType),
3083                                       Context->getSizeType(),
3084                                       SourceLocation(), SourceLocation());
3085     // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
3086     // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases.
3087     // For X86 it is more complicated and some kind of target specific routine
3088     // is needed to decide what to do.
3089     unsigned IntSize =
3090       static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
3091     IntegerLiteral *limit = new (Context) IntegerLiteral(llvm::APInt(IntSize, 8),
3092                                                Context->IntTy,
3093                                                SourceLocation());
3094     BinaryOperator *lessThanExpr = new (Context) BinaryOperator(sizeofExpr, limit,
3095                                                       BinaryOperator::LE,
3096                                                       Context->IntTy,
3097                                                       SourceLocation());
3098     // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
3099     ConditionalOperator *CondExpr =
3100       new (Context) ConditionalOperator(lessThanExpr,
3101                                         SourceLocation(), CE,
3102                                         SourceLocation(), STCE, returnType);
3103     ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), CondExpr);
3104   }
3105   // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
3106   return ReplacingStmt;
3107 }
3108
3109 Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
3110   Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(),
3111                                          Exp->getLocEnd());
3112
3113   // Now do the actual rewrite.
3114   ReplaceStmt(Exp, ReplacingStmt);
3115
3116   // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
3117   return ReplacingStmt;
3118 }
3119
3120 // typedef struct objc_object Protocol;
3121 QualType RewriteObjC::getProtocolType() {
3122   if (!ProtocolTypeDecl) {
3123     TypeSourceInfo *TInfo
3124       = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
3125     ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
3126                                            SourceLocation(),
3127                                            &Context->Idents.get("Protocol"),
3128                                            TInfo);
3129   }
3130   return Context->getTypeDeclType(ProtocolTypeDecl);
3131 }
3132
3133 /// RewriteObjCProtocolExpr - Rewrite a protocol expression into
3134 /// a synthesized/forward data reference (to the protocol's metadata).
3135 /// The forward references (and metadata) are generated in
3136 /// RewriteObjC::HandleTranslationUnit().
3137 Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
3138   std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
3139   IdentifierInfo *ID = &Context->Idents.get(Name);
3140   VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
3141                                 ID, getProtocolType(), 0,
3142                                 VarDecl::Extern, VarDecl::None);
3143   DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation());
3144   Expr *DerefExpr = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
3145                              Context->getPointerType(DRE->getType()),
3146                              SourceLocation());
3147   CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(),
3148                                                 CastExpr::CK_Unknown,
3149                                                 DerefExpr);
3150   ReplaceStmt(Exp, castExpr);
3151   ProtocolExprDecls.insert(Exp->getProtocol());
3152   // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
3153   return castExpr;
3154
3155 }
3156
3157 bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf,
3158                                              const char *endBuf) {
3159   while (startBuf < endBuf) {
3160     if (*startBuf == '#') {
3161       // Skip whitespace.
3162       for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf)
3163         ;
3164       if (!strncmp(startBuf, "if", strlen("if")) ||
3165           !strncmp(startBuf, "ifdef", strlen("ifdef")) ||
3166           !strncmp(startBuf, "ifndef", strlen("ifndef")) ||
3167           !strncmp(startBuf, "define", strlen("define")) ||
3168           !strncmp(startBuf, "undef", strlen("undef")) ||
3169           !strncmp(startBuf, "else", strlen("else")) ||
3170           !strncmp(startBuf, "elif", strlen("elif")) ||
3171           !strncmp(startBuf, "endif", strlen("endif")) ||
3172           !strncmp(startBuf, "pragma", strlen("pragma")) ||
3173           !strncmp(startBuf, "include", strlen("include")) ||
3174           !strncmp(startBuf, "import", strlen("import")) ||
3175           !strncmp(startBuf, "include_next", strlen("include_next")))
3176         return true;
3177     }
3178     startBuf++;
3179   }
3180   return false;
3181 }
3182
3183 /// SynthesizeObjCInternalStruct - Rewrite one internal struct corresponding to
3184 /// an objective-c class with ivars.
3185 void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
3186                                                std::string &Result) {
3187   assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
3188   assert(CDecl->getNameAsCString() &&
3189          "Name missing in SynthesizeObjCInternalStruct");
3190   // Do not synthesize more than once.
3191   if (ObjCSynthesizedStructs.count(CDecl))
3192     return;
3193   ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
3194   int NumIvars = CDecl->ivar_size();
3195   SourceLocation LocStart = CDecl->getLocStart();
3196   SourceLocation LocEnd = CDecl->getLocEnd();
3197
3198   const char *startBuf = SM->getCharacterData(LocStart);
3199   const char *endBuf = SM->getCharacterData(LocEnd);
3200
3201   // If no ivars and no root or if its root, directly or indirectly,
3202   // have no ivars (thus not synthesized) then no need to synthesize this class.
3203   if ((CDecl->isForwardDecl() || NumIvars == 0) &&
3204       (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3205     endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
3206     ReplaceText(LocStart, endBuf-startBuf, Result);
3207     return;
3208   }
3209
3210   // FIXME: This has potential of causing problem. If
3211   // SynthesizeObjCInternalStruct is ever called recursively.
3212   Result += "\nstruct ";
3213   Result += CDecl->getNameAsString();
3214   if (LangOpts.Microsoft)
3215     Result += "_IMPL";
3216
3217   if (NumIvars > 0) {
3218     const char *cursor = strchr(startBuf, '{');
3219     assert((cursor && endBuf)
3220            && "SynthesizeObjCInternalStruct - malformed @interface");
3221     // If the buffer contains preprocessor directives, we do more fine-grained
3222     // rewrites. This is intended to fix code that looks like (which occurs in
3223     // NSURL.h, for example):
3224     //
3225     // #ifdef XYZ
3226     // @interface Foo : NSObject
3227     // #else
3228     // @interface FooBar : NSObject
3229     // #endif
3230     // {
3231     //    int i;
3232     // }
3233     // @end
3234     //
3235     // This clause is segregated to avoid breaking the common case.
3236     if (BufferContainsPPDirectives(startBuf, cursor)) {
3237       SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() :
3238                                   CDecl->getClassLoc();
3239       const char *endHeader = SM->getCharacterData(L);
3240       endHeader += Lexer::MeasureTokenLength(L, *SM, LangOpts);
3241
3242       if (CDecl->protocol_begin() != CDecl->protocol_end()) {
3243         // advance to the end of the referenced protocols.
3244         while (endHeader < cursor && *endHeader != '>') endHeader++;
3245         endHeader++;
3246       }
3247       // rewrite the original header
3248       ReplaceText(LocStart, endHeader-startBuf, Result);
3249     } else {
3250       // rewrite the original header *without* disturbing the '{'
3251       ReplaceText(LocStart, cursor-startBuf, Result);
3252     }
3253     if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3254       Result = "\n    struct ";
3255       Result += RCDecl->getNameAsString();
3256       Result += "_IMPL ";
3257       Result += RCDecl->getNameAsString();
3258       Result += "_IVARS;\n";
3259
3260       // insert the super class structure definition.
3261       SourceLocation OnePastCurly =
3262         LocStart.getFileLocWithOffset(cursor-startBuf+1);
3263       InsertText(OnePastCurly, Result);
3264     }
3265     cursor++; // past '{'
3266
3267     // Now comment out any visibility specifiers.
3268     while (cursor < endBuf) {
3269       if (*cursor == '@') {
3270         SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
3271         // Skip whitespace.
3272         for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor)
3273           /*scan*/;
3274
3275         // FIXME: presence of @public, etc. inside comment results in
3276         // this transformation as well, which is still correct c-code.
3277         if (!strncmp(cursor, "public", strlen("public")) ||
3278             !strncmp(cursor, "private", strlen("private")) ||
3279             !strncmp(cursor, "package", strlen("package")) ||
3280             !strncmp(cursor, "protected", strlen("protected")))
3281           InsertText(atLoc, "// ");
3282       }
3283       // FIXME: If there are cases where '<' is used in ivar declaration part
3284       // of user code, then scan the ivar list and use needToScanForQualifiers
3285       // for type checking.
3286       else if (*cursor == '<') {
3287         SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
3288         InsertText(atLoc, "/* ");
3289         cursor = strchr(cursor, '>');
3290         cursor++;
3291         atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
3292         InsertText(atLoc, " */");
3293       } else if (*cursor == '^') { // rewrite block specifier.
3294         SourceLocation caretLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
3295         ReplaceText(caretLoc, 1, "*");
3296       }
3297       cursor++;
3298     }
3299     // Don't forget to add a ';'!!
3300     InsertText(LocEnd.getFileLocWithOffset(1), ";");
3301   } else { // we don't have any instance variables - insert super struct.
3302     endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
3303     Result += " {\n    struct ";
3304     Result += RCDecl->getNameAsString();
3305     Result += "_IMPL ";
3306     Result += RCDecl->getNameAsString();
3307     Result += "_IVARS;\n};\n";
3308     ReplaceText(LocStart, endBuf-startBuf, Result);
3309   }
3310   // Mark this struct as having been generated.
3311   if (!ObjCSynthesizedStructs.insert(CDecl))
3312     assert(false && "struct already synthesize- SynthesizeObjCInternalStruct");
3313 }
3314
3315 // RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
3316 /// class methods.
3317 template<typename MethodIterator>
3318 void RewriteObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
3319                                              MethodIterator MethodEnd,
3320                                              bool IsInstanceMethod,
3321                                              const char *prefix,
3322                                              const char *ClassName,
3323                                              std::string &Result) {
3324   if (MethodBegin == MethodEnd) return;
3325
3326   if (!objc_impl_method) {
3327     /* struct _objc_method {
3328        SEL _cmd;
3329        char *method_types;
3330        void *_imp;
3331        }
3332      */
3333     Result += "\nstruct _objc_method {\n";
3334     Result += "\tSEL _cmd;\n";
3335     Result += "\tchar *method_types;\n";
3336     Result += "\tvoid *_imp;\n";
3337     Result += "};\n";
3338
3339     objc_impl_method = true;
3340   }
3341
3342   // Build _objc_method_list for class's methods if needed
3343
3344   /* struct  {
3345    struct _objc_method_list *next_method;
3346    int method_count;
3347    struct _objc_method method_list[];
3348    }
3349    */
3350   unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
3351   Result += "\nstatic struct {\n";
3352   Result += "\tstruct _objc_method_list *next_method;\n";
3353   Result += "\tint method_count;\n";
3354   Result += "\tstruct _objc_method method_list[";
3355   Result += utostr(NumMethods);
3356   Result += "];\n} _OBJC_";
3357   Result += prefix;
3358   Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
3359   Result += "_METHODS_";
3360   Result += ClassName;
3361   Result += " __attribute__ ((used, section (\"__OBJC, __";
3362   Result += IsInstanceMethod ? "inst" : "cls";
3363   Result += "_meth\")))= ";
3364   Result += "{\n\t0, " + utostr(NumMethods) + "\n";
3365
3366   Result += "\t,{{(SEL)\"";
3367   Result += (*MethodBegin)->getSelector().getAsString().c_str();
3368   std::string MethodTypeString;
3369   Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
3370   Result += "\", \"";
3371   Result += MethodTypeString;
3372   Result += "\", (void *)";
3373   Result += MethodInternalNames[*MethodBegin];
3374   Result += "}\n";
3375   for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
3376     Result += "\t  ,{(SEL)\"";
3377     Result += (*MethodBegin)->getSelector().getAsString().c_str();
3378     std::string MethodTypeString;
3379     Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
3380     Result += "\", \"";
3381     Result += MethodTypeString;
3382     Result += "\", (void *)";
3383     Result += MethodInternalNames[*MethodBegin];
3384     Result += "}\n";
3385   }
3386   Result += "\t }\n};\n";
3387 }
3388
3389 /// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
3390 void RewriteObjC::
3391 RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
3392                             const char *ClassName, std::string &Result) {
3393   static bool objc_protocol_methods = false;
3394
3395   // Output struct protocol_methods holder of method selector and type.
3396   if (!objc_protocol_methods && !PDecl->isForwardDecl()) {
3397     /* struct protocol_methods {
3398      SEL _cmd;
3399      char *method_types;
3400      }
3401      */
3402     Result += "\nstruct _protocol_methods {\n";
3403     Result += "\tstruct objc_selector *_cmd;\n";
3404     Result += "\tchar *method_types;\n";
3405     Result += "};\n";
3406
3407     objc_protocol_methods = true;
3408   }
3409   // Do not synthesize the protocol more than once.
3410   if (ObjCSynthesizedProtocols.count(PDecl))
3411     return;
3412
3413     if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
3414       unsigned NumMethods = std::distance(PDecl->instmeth_begin(),
3415                                           PDecl->instmeth_end());
3416     /* struct _objc_protocol_method_list {
3417      int protocol_method_count;
3418      struct protocol_methods protocols[];
3419      }
3420      */
3421     Result += "\nstatic struct {\n";
3422     Result += "\tint protocol_method_count;\n";
3423     Result += "\tstruct _protocol_methods protocol_methods[";
3424     Result += utostr(NumMethods);
3425     Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
3426     Result += PDecl->getNameAsString();
3427     Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
3428       "{\n\t" + utostr(NumMethods) + "\n";
3429
3430     // Output instance methods declared in this protocol.
3431     for (ObjCProtocolDecl::instmeth_iterator
3432            I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
3433          I != E; ++I) {
3434       if (I == PDecl->instmeth_begin())
3435         Result += "\t  ,{{(struct objc_selector *)\"";
3436       else
3437         Result += "\t  ,{(struct objc_selector *)\"";
3438       Result += (*I)->getSelector().getAsString().c_str();
3439       std::string MethodTypeString;
3440       Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
3441       Result += "\", \"";
3442       Result += MethodTypeString;
3443       Result += "\"}\n";
3444     }
3445     Result += "\t }\n};\n";
3446   }
3447
3448   // Output class methods declared in this protocol.
3449   unsigned NumMethods = std::distance(PDecl->classmeth_begin(),
3450                                       PDecl->classmeth_end());
3451   if (NumMethods > 0) {
3452     /* struct _objc_protocol_method_list {
3453      int protocol_method_count;
3454      struct protocol_methods protocols[];
3455      }
3456      */
3457     Result += "\nstatic struct {\n";
3458     Result += "\tint protocol_method_count;\n";
3459     Result += "\tstruct _protocol_methods protocol_methods[";
3460     Result += utostr(NumMethods);
3461     Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
3462     Result += PDecl->getNameAsString();
3463     Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
3464            "{\n\t";
3465     Result += utostr(NumMethods);
3466     Result += "\n";
3467
3468     // Output instance methods declared in this protocol.
3469     for (ObjCProtocolDecl::classmeth_iterator
3470            I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
3471          I != E; ++I) {
3472       if (I == PDecl->classmeth_begin())
3473         Result += "\t  ,{{(struct objc_selector *)\"";
3474       else
3475         Result += "\t  ,{(struct objc_selector *)\"";
3476       Result += (*I)->getSelector().getAsString().c_str();
3477       std::string MethodTypeString;
3478       Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
3479       Result += "\", \"";
3480       Result += MethodTypeString;
3481       Result += "\"}\n";
3482     }
3483     Result += "\t }\n};\n";
3484   }
3485
3486   // Output:
3487   /* struct _objc_protocol {
3488    // Objective-C 1.0 extensions
3489    struct _objc_protocol_extension *isa;
3490    char *protocol_name;
3491    struct _objc_protocol **protocol_list;
3492    struct _objc_protocol_method_list *instance_methods;
3493    struct _objc_protocol_method_list *class_methods;
3494    };
3495    */
3496   static bool objc_protocol = false;
3497   if (!objc_protocol) {
3498     Result += "\nstruct _objc_protocol {\n";
3499     Result += "\tstruct _objc_protocol_extension *isa;\n";
3500     Result += "\tchar *protocol_name;\n";
3501     Result += "\tstruct _objc_protocol **protocol_list;\n";
3502     Result += "\tstruct _objc_protocol_method_list *instance_methods;\n";
3503     Result += "\tstruct _objc_protocol_method_list *class_methods;\n";
3504     Result += "};\n";
3505
3506     objc_protocol = true;
3507   }
3508
3509   Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
3510   Result += PDecl->getNameAsString();
3511   Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
3512     "{\n\t0, \"";
3513   Result += PDecl->getNameAsString();
3514   Result += "\", 0, ";
3515   if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
3516     Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
3517     Result += PDecl->getNameAsString();
3518     Result += ", ";
3519   }
3520   else
3521     Result += "0, ";
3522   if (PDecl->classmeth_begin() != PDecl->classmeth_end()) {
3523     Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
3524     Result += PDecl->getNameAsString();
3525     Result += "\n";
3526   }
3527   else
3528     Result += "0\n";
3529   Result += "};\n";
3530
3531   // Mark this protocol as having been generated.
3532   if (!ObjCSynthesizedProtocols.insert(PDecl))
3533     assert(false && "protocol already synthesized");
3534
3535 }
3536
3537 void RewriteObjC::
3538 RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Protocols,
3539                                 const char *prefix, const char *ClassName,
3540                                 std::string &Result) {
3541   if (Protocols.empty()) return;
3542
3543   for (unsigned i = 0; i != Protocols.size(); i++)
3544     RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result);
3545
3546   // Output the top lovel protocol meta-data for the class.
3547   /* struct _objc_protocol_list {
3548    struct _objc_protocol_list *next;
3549    int    protocol_count;
3550    struct _objc_protocol *class_protocols[];
3551    }
3552    */
3553   Result += "\nstatic struct {\n";
3554   Result += "\tstruct _objc_protocol_list *next;\n";
3555   Result += "\tint    protocol_count;\n";
3556   Result += "\tstruct _objc_protocol *class_protocols[";
3557   Result += utostr(Protocols.size());
3558   Result += "];\n} _OBJC_";
3559   Result += prefix;
3560   Result += "_PROTOCOLS_";
3561   Result += ClassName;
3562   Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
3563     "{\n\t0, ";
3564   Result += utostr(Protocols.size());
3565   Result += "\n";
3566
3567   Result += "\t,{&_OBJC_PROTOCOL_";
3568   Result += Protocols[0]->getNameAsString();
3569   Result += " \n";
3570
3571   for (unsigned i = 1; i != Protocols.size(); i++) {
3572     Result += "\t ,&_OBJC_PROTOCOL_";
3573     Result += Protocols[i]->getNameAsString();
3574     Result += "\n";
3575   }
3576   Result += "\t }\n};\n";
3577 }
3578
3579
3580 /// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
3581 /// implementation.
3582 void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
3583                                               std::string &Result) {
3584   ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
3585   // Find category declaration for this implementation.
3586   ObjCCategoryDecl *CDecl;
3587   for (CDecl = ClassDecl->getCategoryList(); CDecl;
3588        CDecl = CDecl->getNextClassCategory())
3589     if (CDecl->getIdentifier() == IDecl->getIdentifier())
3590       break;
3591
3592   std::string FullCategoryName = ClassDecl->getNameAsString();
3593   FullCategoryName += '_';
3594   FullCategoryName += IDecl->getNameAsString();
3595
3596   // Build _objc_method_list for class's instance methods if needed
3597   llvm::SmallVector<ObjCMethodDecl *, 32>
3598     InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
3599
3600   // If any of our property implementations have associated getters or
3601   // setters, produce metadata for them as well.
3602   for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
3603          PropEnd = IDecl->propimpl_end();
3604        Prop != PropEnd; ++Prop) {
3605     if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
3606       continue;
3607     if (!(*Prop)->getPropertyIvarDecl())
3608       continue;
3609     ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
3610     if (!PD)
3611       continue;
3612     if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
3613       InstanceMethods.push_back(Getter);
3614     if (PD->isReadOnly())
3615       continue;
3616     if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
3617       InstanceMethods.push_back(Setter);
3618   }
3619   RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
3620                              true, "CATEGORY_", FullCategoryName.c_str(),
3621                              Result);
3622
3623   // Build _objc_method_list for class's class methods if needed
3624   RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
3625                              false, "CATEGORY_", FullCategoryName.c_str(),
3626                              Result);
3627
3628   // Protocols referenced in class declaration?
3629   // Null CDecl is case of a category implementation with no category interface
3630   if (CDecl)
3631     RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY",
3632                                     FullCategoryName.c_str(), Result);
3633   /* struct _objc_category {
3634    char *category_name;
3635    char *class_name;
3636    struct _objc_method_list *instance_methods;
3637    struct _objc_method_list *class_methods;
3638    struct _objc_protocol_list *protocols;
3639    // Objective-C 1.0 extensions
3640    uint32_t size;     // sizeof (struct _objc_category)
3641    struct _objc_property_list *instance_properties;  // category's own
3642                                                      // @property decl.
3643    };
3644    */
3645
3646   static bool objc_category = false;
3647   if (!objc_category) {
3648     Result += "\nstruct _objc_category {\n";
3649     Result += "\tchar *category_name;\n";
3650     Result += "\tchar *class_name;\n";
3651     Result += "\tstruct _objc_method_list *instance_methods;\n";
3652     Result += "\tstruct _objc_method_list *class_methods;\n";
3653     Result += "\tstruct _objc_protocol_list *protocols;\n";
3654     Result += "\tunsigned int size;\n";
3655     Result += "\tstruct _objc_property_list *instance_properties;\n";
3656     Result += "};\n";
3657     objc_category = true;
3658   }
3659   Result += "\nstatic struct _objc_category _OBJC_CATEGORY_";
3660   Result += FullCategoryName;
3661   Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
3662   Result += IDecl->getNameAsString();
3663   Result += "\"\n\t, \"";
3664   Result += ClassDecl->getNameAsString();
3665   Result += "\"\n";
3666
3667   if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
3668     Result += "\t, (struct _objc_method_list *)"
3669            "&_OBJC_CATEGORY_INSTANCE_METHODS_";
3670     Result += FullCategoryName;
3671     Result += "\n";
3672   }
3673   else
3674     Result += "\t, 0\n";
3675   if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
3676     Result += "\t, (struct _objc_method_list *)"
3677            "&_OBJC_CATEGORY_CLASS_METHODS_";
3678     Result += FullCategoryName;
3679     Result += "\n";
3680   }
3681   else
3682     Result += "\t, 0\n";
3683
3684   if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) {
3685     Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_";
3686     Result += FullCategoryName;
3687     Result += "\n";
3688   }
3689   else
3690     Result += "\t, 0\n";
3691   Result += "\t, sizeof(struct _objc_category), 0\n};\n";
3692 }
3693
3694 /// SynthesizeIvarOffsetComputation - This rutine synthesizes computation of
3695 /// ivar offset.
3696 void RewriteObjC::SynthesizeIvarOffsetComputation(ObjCContainerDecl *IDecl,
3697                                                   ObjCIvarDecl *ivar,
3698                                                   std::string &Result) {
3699   if (ivar->isBitField()) {
3700     // FIXME: The hack below doesn't work for bitfields. For now, we simply
3701     // place all bitfields at offset 0.
3702     Result += "0";
3703   } else {
3704     Result += "__OFFSETOFIVAR__(struct ";
3705     Result += IDecl->getNameAsString();
3706     if (LangOpts.Microsoft)
3707       Result += "_IMPL";
3708     Result += ", ";
3709     Result += ivar->getNameAsString();
3710     Result += ")";
3711   }
3712 }
3713
3714 //===----------------------------------------------------------------------===//
3715 // Meta Data Emission
3716 //===----------------------------------------------------------------------===//
3717
3718 void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
3719                                            std::string &Result) {
3720   ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
3721
3722   // Explictly declared @interface's are already synthesized.
3723   if (CDecl->isImplicitInterfaceDecl()) {
3724     // FIXME: Implementation of a class with no @interface (legacy) doese not
3725     // produce correct synthesis as yet.
3726     SynthesizeObjCInternalStruct(CDecl, Result);
3727   }
3728
3729   // Build _objc_ivar_list metadata for classes ivars if needed
3730   unsigned NumIvars = !IDecl->ivar_empty()
3731                       ? IDecl->ivar_size()
3732                       : (CDecl ? CDecl->ivar_size() : 0);
3733   if (NumIvars > 0) {
3734     static bool objc_ivar = false;
3735     if (!objc_ivar) {
3736       /* struct _objc_ivar {
3737           char *ivar_name;
3738           char *ivar_type;
3739           int ivar_offset;
3740         };
3741        */
3742       Result += "\nstruct _objc_ivar {\n";
3743       Result += "\tchar *ivar_name;\n";
3744       Result += "\tchar *ivar_type;\n";
3745       Result += "\tint ivar_offset;\n";
3746       Result += "};\n";
3747
3748       objc_ivar = true;
3749     }
3750
3751     /* struct {
3752        int ivar_count;
3753        struct _objc_ivar ivar_list[nIvars];
3754        };
3755      */
3756     Result += "\nstatic struct {\n";
3757     Result += "\tint ivar_count;\n";
3758     Result += "\tstruct _objc_ivar ivar_list[";
3759     Result += utostr(NumIvars);
3760     Result += "];\n} _OBJC_INSTANCE_VARIABLES_";
3761     Result += IDecl->getNameAsString();
3762     Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
3763       "{\n\t";
3764     Result += utostr(NumIvars);
3765     Result += "\n";
3766
3767     ObjCInterfaceDecl::ivar_iterator IVI, IVE;
3768     llvm::SmallVector<ObjCIvarDecl *, 8> IVars;
3769     if (!IDecl->ivar_empty()) {
3770       for (ObjCInterfaceDecl::ivar_iterator
3771              IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end();
3772            IV != IVEnd; ++IV)
3773         IVars.push_back(*IV);
3774       IVI = IDecl->ivar_begin();
3775       IVE = IDecl->ivar_end();
3776     } else {
3777       IVI = CDecl->ivar_begin();
3778       IVE = CDecl->ivar_end();
3779     }
3780     Result += "\t,{{\"";
3781     Result += (*IVI)->getNameAsString();
3782     Result += "\", \"";
3783     std::string TmpString, StrEncoding;
3784     Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI);
3785     QuoteDoublequotes(TmpString, StrEncoding);
3786     Result += StrEncoding;
3787     Result += "\", ";
3788     SynthesizeIvarOffsetComputation(IDecl, *IVI, Result);
3789     Result += "}\n";
3790     for (++IVI; IVI != IVE; ++IVI) {
3791       Result += "\t  ,{\"";
3792       Result += (*IVI)->getNameAsString();
3793       Result += "\", \"";
3794       std::string TmpString, StrEncoding;
3795       Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI);
3796       QuoteDoublequotes(TmpString, StrEncoding);
3797       Result += StrEncoding;
3798       Result += "\", ";
3799       SynthesizeIvarOffsetComputation(IDecl, (*IVI), Result);
3800       Result += "}\n";
3801     }
3802
3803     Result += "\t }\n};\n";
3804   }
3805
3806   // Build _objc_method_list for class's instance methods if needed
3807   llvm::SmallVector<ObjCMethodDecl *, 32>
3808     InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
3809
3810   // If any of our property implementations have associated getters or
3811   // setters, produce metadata for them as well.
3812   for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
3813          PropEnd = IDecl->propimpl_end();
3814        Prop != PropEnd; ++Prop) {
3815     if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
3816       continue;
3817     if (!(*Prop)->getPropertyIvarDecl())
3818       continue;
3819     ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
3820     if (!PD)
3821       continue;
3822     if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
3823       InstanceMethods.push_back(Getter);
3824     if (PD->isReadOnly())
3825       continue;
3826     if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
3827       InstanceMethods.push_back(Setter);
3828   }
3829   RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
3830                              true, "", IDecl->getNameAsCString(), Result);
3831
3832   // Build _objc_method_list for class's class methods if needed
3833   RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
3834                              false, "", IDecl->getNameAsCString(), Result);
3835
3836   // Protocols referenced in class declaration?
3837   RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(),
3838                                   "CLASS", CDecl->getNameAsCString(), Result);
3839
3840   // Declaration of class/meta-class metadata
3841   /* struct _objc_class {
3842    struct _objc_class *isa; // or const char *root_class_name when metadata
3843    const char *super_class_name;
3844    char *name;
3845    long version;
3846    long info;
3847    long instance_size;
3848    struct _objc_ivar_list *ivars;
3849    struct _objc_method_list *methods;
3850    struct objc_cache *cache;
3851    struct objc_protocol_list *protocols;
3852    const char *ivar_layout;
3853    struct _objc_class_ext  *ext;
3854    };
3855   */
3856   static bool objc_class = false;
3857   if (!objc_class) {
3858     Result += "\nstruct _objc_class {\n";
3859     Result += "\tstruct _objc_class *isa;\n";
3860     Result += "\tconst char *super_class_name;\n";
3861     Result += "\tchar *name;\n";
3862     Result += "\tlong version;\n";
3863     Result += "\tlong info;\n";
3864     Result += "\tlong instance_size;\n";
3865     Result += "\tstruct _objc_ivar_list *ivars;\n";
3866     Result += "\tstruct _objc_method_list *methods;\n";
3867     Result += "\tstruct objc_cache *cache;\n";
3868     Result += "\tstruct _objc_protocol_list *protocols;\n";
3869     Result += "\tconst char *ivar_layout;\n";
3870     Result += "\tstruct _objc_class_ext  *ext;\n";
3871     Result += "};\n";
3872     objc_class = true;
3873   }
3874
3875   // Meta-class metadata generation.
3876   ObjCInterfaceDecl *RootClass = 0;
3877   ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
3878   while (SuperClass) {
3879     RootClass = SuperClass;
3880     SuperClass = SuperClass->getSuperClass();
3881   }
3882   SuperClass = CDecl->getSuperClass();
3883
3884   Result += "\nstatic struct _objc_class _OBJC_METACLASS_";
3885   Result += CDecl->getNameAsString();
3886   Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
3887   "{\n\t(struct _objc_class *)\"";
3888   Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString());
3889   Result += "\"";
3890
3891   if (SuperClass) {
3892     Result += ", \"";
3893     Result += SuperClass->getNameAsString();
3894     Result += "\", \"";
3895     Result += CDecl->getNameAsString();
3896     Result += "\"";
3897   }
3898   else {
3899     Result += ", 0, \"";
3900     Result += CDecl->getNameAsString();
3901     Result += "\"";
3902   }
3903   // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
3904   // 'info' field is initialized to CLS_META(2) for metaclass
3905   Result += ", 0,2, sizeof(struct _objc_class), 0";
3906   if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
3907     Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
3908     Result += IDecl->getNameAsString();
3909     Result += "\n";
3910   }
3911   else
3912     Result += ", 0\n";
3913   if (CDecl->protocol_begin() != CDecl->protocol_end()) {
3914     Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
3915     Result += CDecl->getNameAsString();
3916     Result += ",0,0\n";
3917   }
3918   else
3919     Result += "\t,0,0,0,0\n";
3920   Result += "};\n";
3921
3922   // class metadata generation.
3923   Result += "\nstatic struct _objc_class _OBJC_CLASS_";
3924   Result += CDecl->getNameAsString();
3925   Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= "
3926             "{\n\t&_OBJC_METACLASS_";
3927   Result += CDecl->getNameAsString();
3928   if (SuperClass) {
3929     Result += ", \"";
3930     Result += SuperClass->getNameAsString();
3931     Result += "\", \"";
3932     Result += CDecl->getNameAsString();
3933     Result += "\"";
3934   }
3935   else {
3936     Result += ", 0, \"";
3937     Result += CDecl->getNameAsString();
3938     Result += "\"";
3939   }
3940   // 'info' field is initialized to CLS_CLASS(1) for class
3941   Result += ", 0,1";
3942   if (!ObjCSynthesizedStructs.count(CDecl))
3943     Result += ",0";
3944   else {
3945     // class has size. Must synthesize its size.
3946     Result += ",sizeof(struct ";
3947     Result += CDecl->getNameAsString();
3948     if (LangOpts.Microsoft)
3949       Result += "_IMPL";
3950     Result += ")";
3951   }
3952   if (NumIvars > 0) {
3953     Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
3954     Result += CDecl->getNameAsString();
3955     Result += "\n\t";
3956   }
3957   else
3958     Result += ",0";
3959   if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
3960     Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
3961     Result += CDecl->getNameAsString();
3962     Result += ", 0\n\t";
3963   }
3964   else
3965     Result += ",0,0";
3966   if (CDecl->protocol_begin() != CDecl->protocol_end()) {
3967     Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
3968     Result += CDecl->getNameAsString();
3969     Result += ", 0,0\n";
3970   }
3971   else
3972     Result += ",0,0,0\n";
3973   Result += "};\n";
3974 }
3975
3976 /// RewriteImplementations - This routine rewrites all method implementations
3977 /// and emits meta-data.
3978
3979 void RewriteObjC::RewriteImplementations() {
3980   int ClsDefCount = ClassImplementation.size();
3981   int CatDefCount = CategoryImplementation.size();
3982
3983   // Rewrite implemented methods
3984   for (int i = 0; i < ClsDefCount; i++)
3985     RewriteImplementationDecl(ClassImplementation[i]);
3986
3987   for (int i = 0; i < CatDefCount; i++)
3988     RewriteImplementationDecl(CategoryImplementation[i]);
3989 }
3990
3991 void RewriteObjC::SynthesizeMetaDataIntoBuffer(std::string &Result) {
3992   int ClsDefCount = ClassImplementation.size();
3993   int CatDefCount = CategoryImplementation.size();
3994   
3995   // For each implemented class, write out all its meta data.
3996   for (int i = 0; i < ClsDefCount; i++)
3997     RewriteObjCClassMetaData(ClassImplementation[i], Result);
3998
3999   // For each implemented category, write out all its meta data.
4000   for (int i = 0; i < CatDefCount; i++)
4001     RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
4002
4003   // Write objc_symtab metadata
4004   /*
4005    struct _objc_symtab
4006    {
4007    long sel_ref_cnt;
4008    SEL *refs;
4009    short cls_def_cnt;
4010    short cat_def_cnt;
4011    void *defs[cls_def_cnt + cat_def_cnt];
4012    };
4013    */
4014
4015   Result += "\nstruct _objc_symtab {\n";
4016   Result += "\tlong sel_ref_cnt;\n";
4017   Result += "\tSEL *refs;\n";
4018   Result += "\tshort cls_def_cnt;\n";
4019   Result += "\tshort cat_def_cnt;\n";
4020   Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n";
4021   Result += "};\n\n";
4022
4023   Result += "static struct _objc_symtab "
4024          "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n";
4025   Result += "\t0, 0, " + utostr(ClsDefCount)
4026             + ", " + utostr(CatDefCount) + "\n";
4027   for (int i = 0; i < ClsDefCount; i++) {
4028     Result += "\t,&_OBJC_CLASS_";
4029     Result += ClassImplementation[i]->getNameAsString();
4030     Result += "\n";
4031   }
4032
4033   for (int i = 0; i < CatDefCount; i++) {
4034     Result += "\t,&_OBJC_CATEGORY_";
4035     Result += CategoryImplementation[i]->getClassInterface()->getNameAsString();
4036     Result += "_";
4037     Result += CategoryImplementation[i]->getNameAsString();
4038     Result += "\n";
4039   }
4040
4041   Result += "};\n\n";
4042
4043   // Write objc_module metadata
4044
4045   /*
4046    struct _objc_module {
4047     long version;
4048     long size;
4049     const char *name;
4050     struct _objc_symtab *symtab;
4051    }
4052   */
4053
4054   Result += "\nstruct _objc_module {\n";
4055   Result += "\tlong version;\n";
4056   Result += "\tlong size;\n";
4057   Result += "\tconst char *name;\n";
4058   Result += "\tstruct _objc_symtab *symtab;\n";
4059   Result += "};\n\n";
4060   Result += "static struct _objc_module "
4061     "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n";
4062   Result += "\t" + utostr(OBJC_ABI_VERSION) +
4063   ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
4064   Result += "};\n\n";
4065
4066   if (LangOpts.Microsoft) {
4067     if (ProtocolExprDecls.size()) {
4068       Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n";
4069       Result += "#pragma data_seg(push, \".objc_protocol$B\")\n";
4070       for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
4071            E = ProtocolExprDecls.end(); I != E; ++I) {
4072         Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_";
4073         Result += (*I)->getNameAsString();
4074         Result += " = &_OBJC_PROTOCOL_";
4075         Result += (*I)->getNameAsString();
4076         Result += ";\n";
4077       }
4078       Result += "#pragma data_seg(pop)\n\n";
4079     }
4080     Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n";
4081     Result += "#pragma data_seg(push, \".objc_module_info$B\")\n";
4082     Result += "static struct _objc_module *_POINTER_OBJC_MODULES = ";
4083     Result += "&_OBJC_MODULES;\n";
4084     Result += "#pragma data_seg(pop)\n\n";
4085   }
4086 }
4087
4088 void RewriteObjC::RewriteByRefString(std::string &ResultStr, 
4089                                      const std::string &Name,
4090                                      ValueDecl *VD) {
4091   assert(BlockByRefDeclNo.count(VD) && 
4092          "RewriteByRefString: ByRef decl missing");
4093   ResultStr += "struct __Block_byref_" + Name + 
4094     "_" + utostr(BlockByRefDeclNo[VD]) ;
4095 }
4096
4097 static bool HasLocalVariableExternalStorage(ValueDecl *VD) {
4098   if (VarDecl *Var = dyn_cast<VarDecl>(VD))
4099     return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4100   return false;
4101 }
4102
4103 std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
4104                                                    const char *funcName,
4105                                                    std::string Tag) {
4106   const FunctionType *AFT = CE->getFunctionType();
4107   QualType RT = AFT->getResultType();
4108   std::string StructRef = "struct " + Tag;
4109   std::string S = "static " + RT.getAsString(Context->PrintingPolicy) + " __" +
4110                   funcName + "_" + "block_func_" + utostr(i);
4111
4112   BlockDecl *BD = CE->getBlockDecl();
4113
4114   if (isa<FunctionNoProtoType>(AFT)) {
4115     // No user-supplied arguments. Still need to pass in a pointer to the
4116     // block (to reference imported block decl refs).
4117     S += "(" + StructRef + " *__cself)";
4118   } else if (BD->param_empty()) {
4119     S += "(" + StructRef + " *__cself)";
4120   } else {
4121     const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
4122     assert(FT && "SynthesizeBlockFunc: No function proto");
4123     S += '(';
4124     // first add the implicit argument.
4125     S += StructRef + " *__cself, ";
4126     std::string ParamStr;
4127     for (BlockDecl::param_iterator AI = BD->param_begin(),
4128          E = BD->param_end(); AI != E; ++AI) {
4129       if (AI != BD->param_begin()) S += ", ";
4130       ParamStr = (*AI)->getNameAsString();
4131       QualType QT = (*AI)->getType();
4132       if (convertBlockPointerToFunctionPointer(QT))
4133         QT.getAsStringInternal(ParamStr, Context->PrintingPolicy);
4134       else
4135         QT.getAsStringInternal(ParamStr, Context->PrintingPolicy);      
4136       S += ParamStr;
4137     }
4138     if (FT->isVariadic()) {
4139       if (!BD->param_empty()) S += ", ";
4140       S += "...";
4141     }
4142     S += ')';
4143   }
4144   S += " {\n";
4145
4146   // Create local declarations to avoid rewriting all closure decl ref exprs.
4147   // First, emit a declaration for all "by ref" decls.
4148   for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
4149        E = BlockByRefDecls.end(); I != E; ++I) {
4150     S += "  ";
4151     std::string Name = (*I)->getNameAsString();
4152     std::string TypeString;
4153     RewriteByRefString(TypeString, Name, (*I));
4154     TypeString += " *";
4155     Name = TypeString + Name;
4156     S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
4157   }
4158   // Next, emit a declaration for all "by copy" declarations.
4159   for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
4160        E = BlockByCopyDecls.end(); I != E; ++I) {
4161     S += "  ";
4162     // Handle nested closure invocation. For example:
4163     //
4164     //   void (^myImportedClosure)(void);
4165     //   myImportedClosure  = ^(void) { setGlobalInt(x + y); };
4166     //
4167     //   void (^anotherClosure)(void);
4168     //   anotherClosure = ^(void) {
4169     //     myImportedClosure(); // import and invoke the closure
4170     //   };
4171     //
4172     if (isTopLevelBlockPointerType((*I)->getType())) {
4173       RewriteBlockPointerTypeVariable(S, (*I));
4174       S += " = (";
4175       RewriteBlockPointerType(S, (*I)->getType());
4176       S += ")";
4177       S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
4178     }
4179     else {
4180       std::string Name = (*I)->getNameAsString();
4181       QualType QT = (*I)->getType();
4182       if (HasLocalVariableExternalStorage(*I))
4183         QT = Context->getPointerType(QT);
4184       QT.getAsStringInternal(Name, Context->PrintingPolicy);
4185       S += Name + " = __cself->" + 
4186                               (*I)->getNameAsString() + "; // bound by copy\n";
4187     }
4188   }
4189   std::string RewrittenStr = RewrittenBlockExprs[CE];
4190   const char *cstr = RewrittenStr.c_str();
4191   while (*cstr++ != '{') ;
4192   S += cstr;
4193   S += "\n";
4194   return S;
4195 }
4196
4197 std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
4198                                                    const char *funcName,
4199                                                    std::string Tag) {
4200   std::string StructRef = "struct " + Tag;
4201   std::string S = "static void __";
4202
4203   S += funcName;
4204   S += "_block_copy_" + utostr(i);
4205   S += "(" + StructRef;
4206   S += "*dst, " + StructRef;
4207   S += "*src) {";
4208   for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
4209       E = ImportedBlockDecls.end(); I != E; ++I) {
4210     S += "_Block_object_assign((void*)&dst->";
4211     S += (*I)->getNameAsString();
4212     S += ", (void*)src->";
4213     S += (*I)->getNameAsString();
4214     if (BlockByRefDeclsPtrSet.count((*I)))
4215       S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
4216     else
4217       S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
4218   }
4219   S += "}\n";
4220   
4221   S += "\nstatic void __";
4222   S += funcName;
4223   S += "_block_dispose_" + utostr(i);
4224   S += "(" + StructRef;
4225   S += "*src) {";
4226   for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
4227       E = ImportedBlockDecls.end(); I != E; ++I) {
4228     S += "_Block_object_dispose((void*)src->";
4229     S += (*I)->getNameAsString();
4230     if (BlockByRefDeclsPtrSet.count((*I)))
4231       S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
4232     else
4233       S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
4234   }
4235   S += "}\n";
4236   return S;
4237 }
4238
4239 std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
4240                                              std::string Desc) {
4241   std::string S = "\nstruct " + Tag;
4242   std::string Constructor = "  " + Tag;
4243
4244   S += " {\n  struct __block_impl impl;\n";
4245   S += "  struct " + Desc;
4246   S += "* Desc;\n";
4247
4248   Constructor += "(void *fp, "; // Invoke function pointer.
4249   Constructor += "struct " + Desc; // Descriptor pointer.
4250   Constructor += " *desc";
4251
4252   if (BlockDeclRefs.size()) {
4253     // Output all "by copy" declarations.
4254     for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
4255          E = BlockByCopyDecls.end(); I != E; ++I) {
4256       S += "  ";
4257       std::string FieldName = (*I)->getNameAsString();
4258       std::string ArgName = "_" + FieldName;
4259       // Handle nested closure invocation. For example:
4260       //
4261       //   void (^myImportedBlock)(void);
4262       //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
4263       //
4264       //   void (^anotherBlock)(void);
4265       //   anotherBlock = ^(void) {
4266       //     myImportedBlock(); // import and invoke the closure
4267       //   };
4268       //
4269       if (isTopLevelBlockPointerType((*I)->getType())) {
4270         S += "struct __block_impl *";
4271         Constructor += ", void *" + ArgName;
4272       } else {
4273         QualType QT = (*I)->getType();
4274         if (HasLocalVariableExternalStorage(*I))
4275           QT = Context->getPointerType(QT);
4276         QT.getAsStringInternal(FieldName, Context->PrintingPolicy);
4277         QT.getAsStringInternal(ArgName, Context->PrintingPolicy);
4278         Constructor += ", " + ArgName;
4279       }
4280       S += FieldName + ";\n";
4281     }
4282     // Output all "by ref" declarations.
4283     for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
4284          E = BlockByRefDecls.end(); I != E; ++I) {
4285       S += "  ";
4286       std::string FieldName = (*I)->getNameAsString();
4287       std::string ArgName = "_" + FieldName;
4288       // Handle nested closure invocation. For example:
4289       //
4290       //   void (^myImportedBlock)(void);
4291       //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
4292       //
4293       //   void (^anotherBlock)(void);
4294       //   anotherBlock = ^(void) {
4295       //     myImportedBlock(); // import and invoke the closure
4296       //   };
4297       //
4298       if (isTopLevelBlockPointerType((*I)->getType())) {
4299         S += "struct __block_impl *";
4300         Constructor += ", void *" + ArgName;
4301       } else {
4302         std::string TypeString;
4303         RewriteByRefString(TypeString, FieldName, (*I));
4304         TypeString += " *";
4305         FieldName = TypeString + FieldName;
4306         ArgName = TypeString + ArgName;
4307         Constructor += ", " + ArgName;
4308       }
4309       S += FieldName + "; // by ref\n";
4310     }
4311     // Finish writing the constructor.
4312     Constructor += ", int flags=0) {\n";
4313     if (GlobalVarDecl)
4314       Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
4315     else
4316       Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
4317     Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
4318
4319     Constructor += "    Desc = desc;\n";
4320
4321     // Initialize all "by copy" arguments.
4322     for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
4323          E = BlockByCopyDecls.end(); I != E; ++I) {
4324       std::string Name = (*I)->getNameAsString();
4325       Constructor += "    ";
4326       if (isTopLevelBlockPointerType((*I)->getType()))
4327         Constructor += Name + " = (struct __block_impl *)_";
4328       else
4329         Constructor += Name + " = _";
4330       Constructor += Name + ";\n";
4331     }
4332     // Initialize all "by ref" arguments.
4333     for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
4334          E = BlockByRefDecls.end(); I != E; ++I) {
4335       std::string Name = (*I)->getNameAsString();
4336       Constructor += "    ";
4337       if (isTopLevelBlockPointerType((*I)->getType()))
4338         Constructor += Name + " = (struct __block_impl *)_";
4339       else
4340         Constructor += Name + " = _";
4341       Constructor += Name + "->__forwarding;\n";
4342     }
4343   } else {
4344     // Finish writing the constructor.
4345     Constructor += ", int flags=0) {\n";
4346     if (GlobalVarDecl)
4347       Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
4348     else
4349       Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
4350     Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
4351     Constructor += "    Desc = desc;\n";
4352   }
4353   Constructor += "  ";
4354   Constructor += "}\n";
4355   S += Constructor;
4356   S += "};\n";
4357   return S;
4358 }
4359
4360 std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, 
4361                                                    std::string ImplTag, int i,
4362                                                    const char *FunName,
4363                                                    unsigned hasCopy) {
4364   std::string S = "\nstatic struct " + DescTag;
4365   
4366   S += " {\n  unsigned long reserved;\n";
4367   S += "  unsigned long Block_size;\n";
4368   if (hasCopy) {
4369     S += "  void (*copy)(struct ";
4370     S += ImplTag; S += "*, struct ";
4371     S += ImplTag; S += "*);\n";
4372     
4373     S += "  void (*dispose)(struct ";
4374     S += ImplTag; S += "*);\n";
4375   }
4376   S += "} ";
4377
4378   S += DescTag + "_DATA = { 0, sizeof(struct ";
4379   S += ImplTag + ")";
4380   if (hasCopy) {
4381     S += ", __" + std::string(FunName) + "_block_copy_" + utostr(i);
4382     S += ", __" + std::string(FunName) + "_block_dispose_" + utostr(i);
4383   }
4384   S += "};\n";
4385   return S;
4386 }
4387
4388 void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
4389                                           const char *FunName) {
4390   // Insert declaration for the function in which block literal is used.
4391   if (CurFunctionDeclToDeclareForBlock && !Blocks.empty())
4392     RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
4393   bool RewriteSC = (GlobalVarDecl &&
4394                     !Blocks.empty() &&
4395                     GlobalVarDecl->getStorageClass() == VarDecl::Static &&
4396                     GlobalVarDecl->getType().getCVRQualifiers());
4397   if (RewriteSC) {
4398     std::string SC(" void __");
4399     SC += GlobalVarDecl->getNameAsString();
4400     SC += "() {}";
4401     InsertText(FunLocStart, SC);
4402   }
4403   
4404   // Insert closures that were part of the function.
4405   for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
4406     CollectBlockDeclRefInfo(Blocks[i]);
4407     // Need to copy-in the inner copied-in variables not actually used in this
4408     // block.
4409     for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
4410       BlockDeclRefExpr *Exp = InnerDeclRefs[count++];
4411       ValueDecl *VD = Exp->getDecl();
4412       BlockDeclRefs.push_back(Exp);
4413       if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
4414         BlockByCopyDeclsPtrSet.insert(VD);
4415         BlockByCopyDecls.push_back(VD);
4416       }
4417       if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
4418         BlockByRefDeclsPtrSet.insert(VD);
4419         BlockByRefDecls.push_back(VD);
4420       }
4421     }
4422
4423     std::string ImplTag = "__" + std::string(FunName) + "_block_impl_" + utostr(i);
4424     std::string DescTag = "__" + std::string(FunName) + "_block_desc_" + utostr(i);
4425
4426     std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4427
4428     InsertText(FunLocStart, CI);
4429
4430     std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4431
4432     InsertText(FunLocStart, CF);
4433
4434     if (ImportedBlockDecls.size()) {
4435       std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4436       InsertText(FunLocStart, HF);
4437     }
4438     std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4439                                                ImportedBlockDecls.size() > 0);
4440     InsertText(FunLocStart, BD);
4441
4442     BlockDeclRefs.clear();
4443     BlockByRefDecls.clear();
4444     BlockByRefDeclsPtrSet.clear();
4445     BlockByCopyDecls.clear();
4446     BlockByCopyDeclsPtrSet.clear();
4447     ImportedBlockDecls.clear();
4448   }
4449   if (RewriteSC) {
4450     // Must insert any 'const/volatile/static here. Since it has been
4451     // removed as result of rewriting of block literals.
4452     std::string SC;
4453     if (GlobalVarDecl->getStorageClass() == VarDecl::Static)
4454       SC = "static ";
4455     if (GlobalVarDecl->getType().isConstQualified())
4456       SC += "const ";
4457     if (GlobalVarDecl->getType().isVolatileQualified())
4458       SC += "volatile ";
4459     if (GlobalVarDecl->getType().isRestrictQualified())
4460       SC += "restrict ";
4461     InsertText(FunLocStart, SC);
4462   }
4463   
4464   Blocks.clear();
4465   InnerDeclRefsCount.clear();
4466   InnerDeclRefs.clear();
4467   RewrittenBlockExprs.clear();
4468 }
4469
4470 void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
4471   SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
4472   const char *FuncName = FD->getNameAsCString();
4473
4474   SynthesizeBlockLiterals(FunLocStart, FuncName);
4475 }
4476
4477 static void BuildUniqueMethodName(std::string &Name,
4478                                   ObjCMethodDecl *MD) {
4479   ObjCInterfaceDecl *IFace = MD->getClassInterface();
4480   Name = IFace->getNameAsCString();
4481   Name += "__" + MD->getSelector().getAsString();
4482   // Convert colons to underscores.
4483   std::string::size_type loc = 0;
4484   while ((loc = Name.find(":", loc)) != std::string::npos)
4485     Name.replace(loc, 1, "_");
4486 }
4487
4488 void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
4489   //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
4490   //SourceLocation FunLocStart = MD->getLocStart();
4491   SourceLocation FunLocStart = MD->getLocStart();
4492   std::string FuncName;
4493   BuildUniqueMethodName(FuncName, MD);
4494   SynthesizeBlockLiterals(FunLocStart, FuncName.c_str());
4495 }
4496
4497 void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) {
4498   for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
4499        CI != E; ++CI)
4500     if (*CI) {
4501       if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
4502         GetBlockDeclRefExprs(CBE->getBody());
4503       else
4504         GetBlockDeclRefExprs(*CI);
4505     }
4506   // Handle specific things.
4507   if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) {
4508     // FIXME: Handle enums.
4509     if (!isa<FunctionDecl>(CDRE->getDecl()))
4510       BlockDeclRefs.push_back(CDRE);
4511   }
4512   else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
4513     if (HasLocalVariableExternalStorage(DRE->getDecl())) {
4514         BlockDeclRefExpr *BDRE = 
4515           new (Context)BlockDeclRefExpr(DRE->getDecl(), DRE->getType(), 
4516                                         DRE->getLocation(), false);
4517         BlockDeclRefs.push_back(BDRE);
4518     }
4519   
4520   return;
4521 }
4522
4523 void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, 
4524                 llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
4525                 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
4526   for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
4527        CI != E; ++CI)
4528     if (*CI) {
4529       if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
4530         InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4531         GetInnerBlockDeclRefExprs(CBE->getBody(),
4532                                   InnerBlockDeclRefs,
4533                                   InnerContexts);
4534       }
4535       else
4536         GetInnerBlockDeclRefExprs(*CI,
4537                                   InnerBlockDeclRefs,
4538                                   InnerContexts);
4539
4540     }
4541   // Handle specific things.
4542   if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) {
4543     if (!isa<FunctionDecl>(CDRE->getDecl()) &&
4544         !InnerContexts.count(CDRE->getDecl()->getDeclContext()))
4545       InnerBlockDeclRefs.push_back(CDRE);
4546   }
4547   else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4548     if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
4549       if (Var->isFunctionOrMethodVarDecl())
4550         ImportedLocalExternalDecls.insert(Var);
4551   }
4552   
4553   return;
4554 }
4555
4556 /// convertFunctionTypeOfBlocks - This routine converts a function type
4557 /// whose result type may be a block pointer or whose argument type(s)
4558 /// might be block pointers to an equivalent funtion type replacing
4559 /// all block pointers to function pointers.
4560 QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {
4561   const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
4562   // FTP will be null for closures that don't take arguments.
4563   // Generate a funky cast.
4564   llvm::SmallVector<QualType, 8> ArgTypes;
4565   QualType Res = FT->getResultType();
4566   bool HasBlockType = convertBlockPointerToFunctionPointer(Res);
4567   
4568   if (FTP) {
4569     for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
4570          E = FTP->arg_type_end(); I && (I != E); ++I) {
4571       QualType t = *I;
4572       // Make sure we convert "t (^)(...)" to "t (*)(...)".
4573       if (convertBlockPointerToFunctionPointer(t))
4574         HasBlockType = true;
4575       ArgTypes.push_back(t);
4576     }
4577   }
4578   QualType FuncType;
4579   // FIXME. Does this work if block takes no argument but has a return type
4580   // which is of block type?
4581   if (HasBlockType)
4582     FuncType = Context->getFunctionType(Res,
4583                         &ArgTypes[0], ArgTypes.size(), false/*no variadic*/, 0,
4584                         false, false, 0, 0, FunctionType::ExtInfo());
4585   else FuncType = QualType(FT, 0);
4586   return FuncType;
4587 }
4588
4589 Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
4590   // Navigate to relevant type information.
4591   const BlockPointerType *CPT = 0;
4592
4593   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4594     CPT = DRE->getType()->getAs<BlockPointerType>();
4595   } else if (const BlockDeclRefExpr *CDRE = 
4596               dyn_cast<BlockDeclRefExpr>(BlockExp)) {
4597     CPT = CDRE->getType()->getAs<BlockPointerType>();
4598   } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4599     CPT = MExpr->getType()->getAs<BlockPointerType>();
4600   } 
4601   else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4602     return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4603   }
4604   else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 
4605     CPT = IEXPR->getType()->getAs<BlockPointerType>();
4606   else if (const ConditionalOperator *CEXPR = 
4607             dyn_cast<ConditionalOperator>(BlockExp)) {
4608     Expr *LHSExp = CEXPR->getLHS();
4609     Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4610     Expr *RHSExp = CEXPR->getRHS();
4611     Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4612     Expr *CONDExp = CEXPR->getCond();
4613     ConditionalOperator *CondExpr =
4614       new (Context) ConditionalOperator(CONDExp,
4615                                       SourceLocation(), cast<Expr>(LHSStmt),
4616                                       SourceLocation(), cast<Expr>(RHSStmt), 
4617                                       Exp->getType());
4618     return CondExpr;
4619   } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4620     CPT = IRE->getType()->getAs<BlockPointerType>();
4621   } else {
4622     assert(1 && "RewriteBlockClass: Bad type");
4623   }
4624   assert(CPT && "RewriteBlockClass: Bad type");
4625   const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>();
4626   assert(FT && "RewriteBlockClass: Bad type");
4627   const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
4628   // FTP will be null for closures that don't take arguments.
4629
4630   RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
4631                                       SourceLocation(),
4632                                       &Context->Idents.get("__block_impl"));
4633   QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
4634
4635   // Generate a funky cast.
4636   llvm::SmallVector<QualType, 8> ArgTypes;
4637
4638   // Push the block argument type.
4639   ArgTypes.push_back(PtrBlock);
4640   if (FTP) {
4641     for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
4642          E = FTP->arg_type_end(); I && (I != E); ++I) {
4643       QualType t = *I;
4644       // Make sure we convert "t (^)(...)" to "t (*)(...)".
4645       (void)convertBlockPointerToFunctionPointer(t);
4646       ArgTypes.push_back(t);
4647     }
4648   }
4649   // Now do the pointer to function cast.
4650   QualType PtrToFuncCastType = Context->getFunctionType(Exp->getType(),
4651     &ArgTypes[0], ArgTypes.size(), false/*no variadic*/, 0,
4652                                                         false, false, 0, 0, 
4653                                                        FunctionType::ExtInfo());
4654
4655   PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
4656
4657   CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4658                                                CastExpr::CK_Unknown,
4659                                                const_cast<Expr*>(BlockExp));
4660   // Don't forget the parens to enforce the proper binding.
4661   ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
4662                                           BlkCast);
4663   //PE->dump();
4664
4665   FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
4666                      &Context->Idents.get("FuncPtr"), Context->VoidPtrTy, 0,
4667                                     /*BitWidth=*/0, /*Mutable=*/true);
4668   MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
4669                                             FD->getType());
4670
4671   CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4672                                                 CastExpr::CK_Unknown, ME);
4673   PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast);
4674
4675   llvm::SmallVector<Expr*, 8> BlkExprs;
4676   // Add the implicit argument.
4677   BlkExprs.push_back(BlkCast);
4678   // Add the user arguments.
4679   for (CallExpr::arg_iterator I = Exp->arg_begin(),
4680        E = Exp->arg_end(); I != E; ++I) {
4681     BlkExprs.push_back(*I);
4682   }
4683   CallExpr *CE = new (Context) CallExpr(*Context, PE, &BlkExprs[0],
4684                                         BlkExprs.size(),
4685                                         Exp->getType(), SourceLocation());
4686   return CE;
4687 }
4688
4689 void RewriteObjC::RewriteBlockCall(CallExpr *Exp) {
4690   Stmt *BlockCall = SynthesizeBlockCall(Exp, Exp->getCallee());
4691   ReplaceStmt(Exp, BlockCall);
4692 }
4693
4694 // We need to return the rewritten expression to handle cases where the
4695 // BlockDeclRefExpr is embedded in another expression being rewritten.
4696 // For example:
4697 //
4698 // int main() {
4699 //    __block Foo *f;
4700 //    __block int i;
4701 //
4702 //    void (^myblock)() = ^() {
4703 //        [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten).
4704 //        i = 77;
4705 //    };
4706 //}
4707 Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) {
4708   // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
4709   // for each DeclRefExp where BYREFVAR is name of the variable.
4710   ValueDecl *VD;
4711   bool isArrow = true;
4712   if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(DeclRefExp))
4713     VD = BDRE->getDecl();
4714   else {
4715     VD = cast<DeclRefExpr>(DeclRefExp)->getDecl();
4716     isArrow = false;
4717   }
4718   
4719   FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
4720                                     &Context->Idents.get("__forwarding"), 
4721                                     Context->VoidPtrTy, 0,
4722                                     /*BitWidth=*/0, /*Mutable=*/true);
4723   MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
4724                                             FD, SourceLocation(),
4725                                             FD->getType());
4726
4727   const char *Name = VD->getNameAsCString();
4728   FD = FieldDecl::Create(*Context, 0, SourceLocation(),
4729                          &Context->Idents.get(Name), 
4730                          Context->VoidPtrTy, 0,
4731                          /*BitWidth=*/0, /*Mutable=*/true);
4732   ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
4733                                 DeclRefExp->getType());
4734   
4735   
4736   
4737   // Need parens to enforce precedence.
4738   ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
4739                                           ME);
4740   ReplaceStmt(DeclRefExp, PE);
4741   return PE;
4742 }
4743
4744 // Rewrites the imported local variable V with external storage 
4745 // (static, extern, etc.) as *V
4746 //
4747 Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
4748   ValueDecl *VD = DRE->getDecl();
4749   if (VarDecl *Var = dyn_cast<VarDecl>(VD))
4750     if (!ImportedLocalExternalDecls.count(Var))
4751       return DRE;
4752   Expr *Exp = new (Context) UnaryOperator(DRE, UnaryOperator::Deref,
4753                                     DRE->getType(), DRE->getLocation());
4754   // Need parens to enforce precedence.
4755   ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
4756                                           Exp);
4757   ReplaceStmt(DRE, PE);
4758   return PE;
4759 }
4760
4761 void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {
4762   SourceLocation LocStart = CE->getLParenLoc();
4763   SourceLocation LocEnd = CE->getRParenLoc();
4764
4765   // Need to avoid trying to rewrite synthesized casts.
4766   if (LocStart.isInvalid())
4767     return;
4768   // Need to avoid trying to rewrite casts contained in macros.
4769   if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4770     return;
4771
4772   const char *startBuf = SM->getCharacterData(LocStart);
4773   const char *endBuf = SM->getCharacterData(LocEnd);
4774   QualType QT = CE->getType();
4775   const Type* TypePtr = QT->getAs<Type>();
4776   if (isa<TypeOfExprType>(TypePtr)) {
4777     const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4778     QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
4779     std::string TypeAsString = "(";
4780     RewriteBlockPointerType(TypeAsString, QT);
4781     TypeAsString += ")";
4782     ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4783     return;
4784   }
4785   // advance the location to startArgList.
4786   const char *argPtr = startBuf;
4787
4788   while (*argPtr++ && (argPtr < endBuf)) {
4789     switch (*argPtr) {
4790     case '^':
4791       // Replace the '^' with '*'.
4792       LocStart = LocStart.getFileLocWithOffset(argPtr-startBuf);
4793       ReplaceText(LocStart, 1, "*");
4794       break;
4795     }
4796   }
4797   return;
4798 }
4799
4800 void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
4801   SourceLocation DeclLoc = FD->getLocation();
4802   unsigned parenCount = 0;
4803
4804   // We have 1 or more arguments that have closure pointers.
4805   const char *startBuf = SM->getCharacterData(DeclLoc);
4806   const char *startArgList = strchr(startBuf, '(');
4807
4808   assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
4809
4810   parenCount++;
4811   // advance the location to startArgList.
4812   DeclLoc = DeclLoc.getFileLocWithOffset(startArgList-startBuf);
4813   assert((DeclLoc.isValid()) && "Invalid DeclLoc");
4814
4815   const char *argPtr = startArgList;
4816
4817   while (*argPtr++ && parenCount) {
4818     switch (*argPtr) {
4819     case '^':
4820       // Replace the '^' with '*'.
4821       DeclLoc = DeclLoc.getFileLocWithOffset(argPtr-startArgList);
4822       ReplaceText(DeclLoc, 1, "*");
4823       break;
4824     case '(':
4825       parenCount++;
4826       break;
4827     case ')':
4828       parenCount--;
4829       break;
4830     }
4831   }
4832   return;
4833 }
4834
4835 bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
4836   const FunctionProtoType *FTP;
4837   const PointerType *PT = QT->getAs<PointerType>();
4838   if (PT) {
4839     FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
4840   } else {
4841     const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
4842     assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4843     FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
4844   }
4845   if (FTP) {
4846     for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
4847          E = FTP->arg_type_end(); I != E; ++I)
4848       if (isTopLevelBlockPointerType(*I))
4849         return true;
4850   }
4851   return false;
4852 }
4853
4854 void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
4855                                      const char *&RParen) {
4856   const char *argPtr = strchr(Name, '(');
4857   assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
4858
4859   LParen = argPtr; // output the start.
4860   argPtr++; // skip past the left paren.
4861   unsigned parenCount = 1;
4862
4863   while (*argPtr && parenCount) {
4864     switch (*argPtr) {
4865     case '(': parenCount++; break;
4866     case ')': parenCount--; break;
4867     default: break;
4868     }
4869     if (parenCount) argPtr++;
4870   }
4871   assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
4872   RParen = argPtr; // output the end
4873 }
4874
4875 void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
4876   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
4877     RewriteBlockPointerFunctionArgs(FD);
4878     return;
4879   }
4880   // Handle Variables and Typedefs.
4881   SourceLocation DeclLoc = ND->getLocation();
4882   QualType DeclT;
4883   if (VarDecl *VD = dyn_cast<VarDecl>(ND))
4884     DeclT = VD->getType();
4885   else if (TypedefDecl *TDD = dyn_cast<TypedefDecl>(ND))
4886     DeclT = TDD->getUnderlyingType();
4887   else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4888     DeclT = FD->getType();
4889   else
4890     assert(0 && "RewriteBlockPointerDecl(): Decl type not yet handled");
4891
4892   const char *startBuf = SM->getCharacterData(DeclLoc);
4893   const char *endBuf = startBuf;
4894   // scan backward (from the decl location) for the end of the previous decl.
4895   while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
4896     startBuf--;
4897
4898   // *startBuf != '^' if we are dealing with a pointer to function that
4899   // may take block argument types (which will be handled below).
4900   if (*startBuf == '^') {
4901     // Replace the '^' with '*', computing a negative offset.
4902     DeclLoc = DeclLoc.getFileLocWithOffset(startBuf-endBuf);
4903     ReplaceText(DeclLoc, 1, "*");
4904   }
4905   if (PointerTypeTakesAnyBlockArguments(DeclT)) {
4906     // Replace the '^' with '*' for arguments.
4907     DeclLoc = ND->getLocation();
4908     startBuf = SM->getCharacterData(DeclLoc);
4909     const char *argListBegin, *argListEnd;
4910     GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4911     while (argListBegin < argListEnd) {
4912       if (*argListBegin == '^') {
4913         SourceLocation CaretLoc = DeclLoc.getFileLocWithOffset(argListBegin-startBuf);
4914         ReplaceText(CaretLoc, 1, "*");
4915       }
4916       argListBegin++;
4917     }
4918   }
4919   return;
4920 }
4921
4922
4923 /// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
4924 /// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
4925 ///                    struct Block_byref_id_object *src) {
4926 ///  _Block_object_assign (&_dest->object, _src->object, 
4927 ///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
4928 ///                        [|BLOCK_FIELD_IS_WEAK]) // object
4929 ///  _Block_object_assign(&_dest->object, _src->object, 
4930 ///                       BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
4931 ///                       [|BLOCK_FIELD_IS_WEAK]) // block
4932 /// }
4933 /// And:
4934 /// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
4935 ///  _Block_object_dispose(_src->object, 
4936 ///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
4937 ///                        [|BLOCK_FIELD_IS_WEAK]) // object
4938 ///  _Block_object_dispose(_src->object, 
4939 ///                         BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
4940 ///                         [|BLOCK_FIELD_IS_WEAK]) // block
4941 /// }
4942
4943 std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
4944                                                           int flag) {
4945   std::string S;
4946   if (CopyDestroyCache.count(flag))
4947     return S;
4948   CopyDestroyCache.insert(flag);
4949   S = "static void __Block_byref_id_object_copy_";
4950   S += utostr(flag);
4951   S += "(void *dst, void *src) {\n";
4952   
4953   // offset into the object pointer is computed as:
4954   // void * + void* + int + int + void* + void *
4955   unsigned IntSize = 
4956   static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
4957   unsigned VoidPtrSize = 
4958   static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
4959   
4960   unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/8;
4961   S += " _Block_object_assign((char*)dst + ";
4962   S += utostr(offset);
4963   S += ", *(void * *) ((char*)src + ";
4964   S += utostr(offset);
4965   S += "), ";
4966   S += utostr(flag);
4967   S += ");\n}\n";
4968   
4969   S += "static void __Block_byref_id_object_dispose_";
4970   S += utostr(flag);
4971   S += "(void *src) {\n";
4972   S += " _Block_object_dispose(*(void * *) ((char*)src + ";
4973   S += utostr(offset);
4974   S += "), ";
4975   S += utostr(flag);
4976   S += ");\n}\n";
4977   return S;
4978 }
4979
4980 /// RewriteByRefVar - For each __block typex ND variable this routine transforms
4981 /// the declaration into:
4982 /// struct __Block_byref_ND {
4983 /// void *__isa;                  // NULL for everything except __weak pointers
4984 /// struct __Block_byref_ND *__forwarding;
4985 /// int32_t __flags;
4986 /// int32_t __size;
4987 /// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
4988 /// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
4989 /// typex ND;
4990 /// };
4991 ///
4992 /// It then replaces declaration of ND variable with:
4993 /// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 
4994 ///                               __size=sizeof(struct __Block_byref_ND), 
4995 ///                               ND=initializer-if-any};
4996 ///
4997 ///
4998 void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
4999   // Insert declaration for the function in which block literal is
5000   // used.
5001   if (CurFunctionDeclToDeclareForBlock)
5002     RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
5003   int flag = 0;
5004   int isa = 0;
5005   SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
5006   if (DeclLoc.isInvalid())
5007     // If type location is missing, it is because of missing type (a warning).
5008     // Use variable's location which is good for this case.
5009     DeclLoc = ND->getLocation();
5010   const char *startBuf = SM->getCharacterData(DeclLoc);
5011   SourceLocation X = ND->getLocEnd();
5012   X = SM->getInstantiationLoc(X);
5013   const char *endBuf = SM->getCharacterData(X);
5014   std::string Name(ND->getNameAsString());
5015   std::string ByrefType;
5016   RewriteByRefString(ByrefType, Name, ND);
5017   ByrefType += " {\n";
5018   ByrefType += "  void *__isa;\n";
5019   RewriteByRefString(ByrefType, Name, ND);
5020   ByrefType += " *__forwarding;\n";
5021   ByrefType += " int __flags;\n";
5022   ByrefType += " int __size;\n";
5023   // Add void *__Block_byref_id_object_copy; 
5024   // void *__Block_byref_id_object_dispose; if needed.
5025   QualType Ty = ND->getType();
5026   bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty);
5027   if (HasCopyAndDispose) {
5028     ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n";
5029     ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n";
5030   }
5031   
5032   Ty.getAsStringInternal(Name, Context->PrintingPolicy);
5033   ByrefType += " " + Name + ";\n";
5034   ByrefType += "};\n";
5035   // Insert this type in global scope. It is needed by helper function.
5036   SourceLocation FunLocStart;
5037   if (CurFunctionDef)
5038      FunLocStart = CurFunctionDef->getTypeSpecStartLoc();
5039   else {
5040     assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
5041     FunLocStart = CurMethodDef->getLocStart();
5042   }
5043   InsertText(FunLocStart, ByrefType);
5044   if (Ty.isObjCGCWeak()) {
5045     flag |= BLOCK_FIELD_IS_WEAK;
5046     isa = 1;
5047   }
5048   
5049   if (HasCopyAndDispose) {
5050     flag = BLOCK_BYREF_CALLER;
5051     QualType Ty = ND->getType();
5052     // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
5053     if (Ty->isBlockPointerType())
5054       flag |= BLOCK_FIELD_IS_BLOCK;
5055     else
5056       flag |= BLOCK_FIELD_IS_OBJECT;
5057     std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5058     if (!HF.empty())
5059       InsertText(FunLocStart, HF);
5060   }
5061   
5062   // struct __Block_byref_ND ND = 
5063   // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 
5064   //  initializer-if-any};
5065   bool hasInit = (ND->getInit() != 0);
5066   unsigned flags = 0;
5067   if (HasCopyAndDispose)
5068     flags |= BLOCK_HAS_COPY_DISPOSE;
5069   Name = ND->getNameAsString();
5070   ByrefType.clear();
5071   RewriteByRefString(ByrefType, Name, ND);
5072   std::string ForwardingCastType("(");
5073   ForwardingCastType += ByrefType + " *)";
5074   if (!hasInit) {
5075     ByrefType += " " + Name + " = {(void*)";
5076     ByrefType += utostr(isa);
5077     ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
5078     ByrefType += utostr(flags);
5079     ByrefType += ", ";
5080     ByrefType += "sizeof(";
5081     RewriteByRefString(ByrefType, Name, ND);
5082     ByrefType += ")";
5083     if (HasCopyAndDispose) {
5084       ByrefType += ", __Block_byref_id_object_copy_";
5085       ByrefType += utostr(flag);
5086       ByrefType += ", __Block_byref_id_object_dispose_";
5087       ByrefType += utostr(flag);
5088     }
5089     ByrefType += "};\n";
5090     ReplaceText(DeclLoc, endBuf-startBuf+Name.size(), ByrefType);
5091   }
5092   else {
5093     SourceLocation startLoc;
5094     Expr *E = ND->getInit();
5095     if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
5096       startLoc = ECE->getLParenLoc();
5097     else
5098       startLoc = E->getLocStart();
5099     startLoc = SM->getInstantiationLoc(startLoc);
5100     endBuf = SM->getCharacterData(startLoc);
5101    
5102     ByrefType += " " + Name;
5103     ByrefType += " = {(void*)";
5104     ByrefType += utostr(isa);
5105     ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
5106     ByrefType += utostr(flags);
5107     ByrefType += ", ";
5108     ByrefType += "sizeof(";
5109     RewriteByRefString(ByrefType, Name, ND);
5110     ByrefType += "), ";
5111     if (HasCopyAndDispose) {
5112       ByrefType += "__Block_byref_id_object_copy_";
5113       ByrefType += utostr(flag);
5114       ByrefType += ", __Block_byref_id_object_dispose_";
5115       ByrefType += utostr(flag);
5116       ByrefType += ", ";
5117     }
5118     ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5119     
5120     // Complete the newly synthesized compound expression by inserting a right
5121     // curly brace before the end of the declaration.
5122     // FIXME: This approach avoids rewriting the initializer expression. It
5123     // also assumes there is only one declarator. For example, the following
5124     // isn't currently supported by this routine (in general):
5125     // 
5126     // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37;
5127     //
5128     const char *startBuf = SM->getCharacterData(startLoc);
5129     const char *semiBuf = strchr(startBuf, ';');
5130     assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'");
5131     SourceLocation semiLoc =
5132       startLoc.getFileLocWithOffset(semiBuf-startBuf);
5133
5134     InsertText(semiLoc, "}");
5135   }
5136   return;
5137 }
5138
5139 void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
5140   // Add initializers for any closure decl refs.
5141   GetBlockDeclRefExprs(Exp->getBody());
5142   if (BlockDeclRefs.size()) {
5143     // Unique all "by copy" declarations.
5144     for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
5145       if (!BlockDeclRefs[i]->isByRef()) {
5146         if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5147           BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5148           BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5149         }
5150       }
5151     // Unique all "by ref" declarations.
5152     for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
5153       if (BlockDeclRefs[i]->isByRef()) {
5154         if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5155           BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5156           BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5157         }
5158       }
5159     // Find any imported blocks...they will need special attention.
5160     for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
5161       if (BlockDeclRefs[i]->isByRef() ||
5162           BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
5163           BlockDeclRefs[i]->getType()->isBlockPointerType())
5164         ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5165   }
5166 }
5167
5168 FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(const char *name) {
5169   IdentifierInfo *ID = &Context->Idents.get(name);
5170   QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
5171   return FunctionDecl::Create(*Context, TUDecl,SourceLocation(),
5172                               ID, FType, 0, FunctionDecl::Extern,
5173                               FunctionDecl::None, false, false);
5174 }
5175
5176 Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
5177           const llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs) {
5178   Blocks.push_back(Exp);
5179
5180   CollectBlockDeclRefInfo(Exp);
5181   
5182   // Add inner imported variables now used in current block.
5183  int countOfInnerDecls = 0;
5184   if (!InnerBlockDeclRefs.empty()) {
5185     for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5186       BlockDeclRefExpr *Exp = InnerBlockDeclRefs[i];
5187       ValueDecl *VD = Exp->getDecl();
5188       if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
5189       // We need to save the copied-in variables in nested
5190       // blocks because it is needed at the end for some of the API generations.
5191       // See SynthesizeBlockLiterals routine.
5192         InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5193         BlockDeclRefs.push_back(Exp);
5194         BlockByCopyDeclsPtrSet.insert(VD);
5195         BlockByCopyDecls.push_back(VD);
5196       }
5197       if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
5198         InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5199         BlockDeclRefs.push_back(Exp);
5200         BlockByRefDeclsPtrSet.insert(VD);
5201         BlockByRefDecls.push_back(VD);
5202       }
5203     }
5204     // Find any imported blocks...they will need special attention.
5205     for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5206       if (InnerBlockDeclRefs[i]->isByRef() ||
5207           InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
5208           InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5209         ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5210   }
5211   InnerDeclRefsCount.push_back(countOfInnerDecls);
5212   
5213   std::string FuncName;
5214
5215   if (CurFunctionDef)
5216     FuncName = CurFunctionDef->getNameAsString();
5217   else if (CurMethodDef)
5218     BuildUniqueMethodName(FuncName, CurMethodDef);
5219   else if (GlobalVarDecl)
5220     FuncName = std::string(GlobalVarDecl->getNameAsString());
5221
5222   std::string BlockNumber = utostr(Blocks.size()-1);
5223
5224   std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber;
5225   std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
5226
5227   // Get a pointer to the function type so we can cast appropriately.
5228   QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5229   QualType FType = Context->getPointerType(BFT);
5230
5231   FunctionDecl *FD;
5232   Expr *NewRep;
5233
5234   // Simulate a contructor call...
5235   FD = SynthBlockInitFunctionDecl(Tag.c_str());
5236   DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, SourceLocation());
5237
5238   llvm::SmallVector<Expr*, 4> InitExprs;
5239
5240   // Initialize the block function.
5241   FD = SynthBlockInitFunctionDecl(Func.c_str());
5242   DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(),
5243                                                SourceLocation());
5244   CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
5245                                                 CastExpr::CK_Unknown, Arg);
5246   InitExprs.push_back(castExpr);
5247
5248   // Initialize the block descriptor.
5249   std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA";
5250
5251   VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 
5252                                     &Context->Idents.get(DescData.c_str()), 
5253                                     Context->VoidPtrTy, 0,
5254                                     VarDecl::Static, VarDecl::None);
5255   UnaryOperator *DescRefExpr = new (Context) UnaryOperator(
5256                                   new (Context) DeclRefExpr(NewVD, 
5257                                     Context->VoidPtrTy, SourceLocation()), 
5258                                   UnaryOperator::AddrOf,
5259                                   Context->getPointerType(Context->VoidPtrTy), 
5260                                   SourceLocation());
5261   InitExprs.push_back(DescRefExpr); 
5262   
5263   // Add initializers for any closure decl refs.
5264   if (BlockDeclRefs.size()) {
5265     Expr *Exp;
5266     // Output all "by copy" declarations.
5267     for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
5268          E = BlockByCopyDecls.end(); I != E; ++I) {
5269       if (isObjCType((*I)->getType())) {
5270         // FIXME: Conform to ABI ([[obj retain] autorelease]).
5271         FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
5272         Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
5273         if (HasLocalVariableExternalStorage(*I)) {
5274           QualType QT = (*I)->getType();
5275           QT = Context->getPointerType(QT);
5276           Exp = new (Context) UnaryOperator(Exp, UnaryOperator::AddrOf, QT,
5277                                             SourceLocation());
5278         }
5279       } else if (isTopLevelBlockPointerType((*I)->getType())) {
5280         FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
5281         Arg = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
5282         Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
5283                                        CastExpr::CK_Unknown, Arg);
5284       } else {
5285         FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
5286         Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
5287         if (HasLocalVariableExternalStorage(*I)) {
5288           QualType QT = (*I)->getType();
5289           QT = Context->getPointerType(QT);
5290           Exp = new (Context) UnaryOperator(Exp, UnaryOperator::AddrOf, QT, 
5291                                             SourceLocation());
5292         }
5293         
5294       }
5295       InitExprs.push_back(Exp);
5296     }
5297     // Output all "by ref" declarations.
5298     for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
5299          E = BlockByRefDecls.end(); I != E; ++I) {
5300       ValueDecl *ND = (*I);
5301       std::string Name(ND->getNameAsString());
5302       std::string RecName;
5303       RewriteByRefString(RecName, Name, ND);
5304       IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 
5305                                                 + sizeof("struct"));
5306       RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
5307                                           SourceLocation(), II);
5308       assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
5309       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
5310       
5311       FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
5312       Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
5313       Exp = new (Context) UnaryOperator(Exp, UnaryOperator::AddrOf,
5314                               Context->getPointerType(Exp->getType()),
5315                               SourceLocation());
5316       Exp = NoTypeInfoCStyleCastExpr(Context, castT, CastExpr::CK_Unknown, Exp);
5317       InitExprs.push_back(Exp);
5318     }
5319   }
5320   if (ImportedBlockDecls.size()) {
5321     // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
5322     int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR);
5323     unsigned IntSize = 
5324       static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
5325     Expr *FlagExp = new (Context) IntegerLiteral(llvm::APInt(IntSize, flag), 
5326                                              Context->IntTy, SourceLocation());
5327     InitExprs.push_back(FlagExp);
5328   }
5329   NewRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(),
5330                                   FType, SourceLocation());
5331   NewRep = new (Context) UnaryOperator(NewRep, UnaryOperator::AddrOf,
5332                              Context->getPointerType(NewRep->getType()),
5333                              SourceLocation());
5334   NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CastExpr::CK_Unknown,
5335                                     NewRep);
5336   BlockDeclRefs.clear();
5337   BlockByRefDecls.clear();
5338   BlockByRefDeclsPtrSet.clear();
5339   BlockByCopyDecls.clear();
5340   BlockByCopyDeclsPtrSet.clear();
5341   ImportedBlockDecls.clear();
5342   return NewRep;
5343 }
5344
5345 //===----------------------------------------------------------------------===//
5346 // Function Body / Expression rewriting
5347 //===----------------------------------------------------------------------===//
5348
5349 // This is run as a first "pass" prior to RewriteFunctionBodyOrGlobalInitializer().
5350 // The allows the main rewrite loop to associate all ObjCPropertyRefExprs with
5351 // their respective BinaryOperator. Without this knowledge, we'd need to rewrite
5352 // the ObjCPropertyRefExpr twice (once as a getter, and later as a setter).
5353 // Since the rewriter isn't capable of rewriting rewritten code, it's important
5354 // we get this right.
5355 void RewriteObjC::CollectPropertySetters(Stmt *S) {
5356   // Perform a bottom up traversal of all children.
5357   for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
5358        CI != E; ++CI)
5359     if (*CI)
5360       CollectPropertySetters(*CI);
5361
5362   if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
5363     if (BinOp->isAssignmentOp()) {
5364       if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(BinOp->getLHS()))
5365         PropSetters[PRE] = BinOp;
5366     }
5367   }
5368 }
5369
5370 Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
5371   if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5372       isa<DoStmt>(S) || isa<ForStmt>(S))
5373     Stmts.push_back(S);
5374   else if (isa<ObjCForCollectionStmt>(S)) {
5375     Stmts.push_back(S);
5376     ObjCBcLabelNo.push_back(++BcLabelCount);
5377   }
5378
5379   SourceRange OrigStmtRange = S->getSourceRange();
5380
5381   // Perform a bottom up rewrite of all children.
5382   for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
5383        CI != E; ++CI)
5384     if (*CI) {
5385       Stmt *newStmt;
5386       Stmt *S = (*CI);
5387       if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5388         Expr *OldBase = IvarRefExpr->getBase();
5389         bool replaced = false;
5390         newStmt = RewriteObjCNestedIvarRefExpr(S, replaced);
5391         if (replaced) {
5392           if (ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(newStmt))
5393             ReplaceStmt(OldBase, IRE->getBase());
5394           else
5395             ReplaceStmt(S, newStmt);
5396         }
5397       }
5398       else
5399         newStmt = RewriteFunctionBodyOrGlobalInitializer(S);
5400       if (newStmt)
5401         *CI = newStmt;
5402     }
5403
5404   if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5405     llvm::SmallVector<BlockDeclRefExpr *, 8> InnerBlockDeclRefs;
5406     llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
5407     InnerContexts.insert(BE->getBlockDecl());
5408     ImportedLocalExternalDecls.clear();
5409     GetInnerBlockDeclRefExprs(BE->getBody(),
5410                               InnerBlockDeclRefs, InnerContexts);
5411     // Rewrite the block body in place.
5412     RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5413     ImportedLocalExternalDecls.clear();
5414     // Now we snarf the rewritten text and stash it away for later use.
5415     std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
5416     RewrittenBlockExprs[BE] = Str;
5417
5418     Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5419                             
5420     //blockTranscribed->dump();
5421     ReplaceStmt(S, blockTranscribed);
5422     return blockTranscribed;
5423   }
5424   // Handle specific things.
5425   if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
5426     return RewriteAtEncode(AtEncode);
5427
5428   if (ObjCPropertyRefExpr *PropRefExpr = dyn_cast<ObjCPropertyRefExpr>(S)) {
5429     BinaryOperator *BinOp = PropSetters[PropRefExpr];
5430     if (BinOp) {
5431       // Because the rewriter doesn't allow us to rewrite rewritten code,
5432       // we need to rewrite the right hand side prior to rewriting the setter.
5433       DisableReplaceStmt = true;
5434       // Save the source range. Even if we disable the replacement, the
5435       // rewritten node will have been inserted into the tree. If the synthesized
5436       // node is at the 'end', the rewriter will fail. Consider this:
5437       //    self.errorHandler = handler ? handler :
5438       //              ^(NSURL *errorURL, NSError *error) { return (BOOL)1; };
5439       SourceRange SrcRange = BinOp->getSourceRange();
5440       Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(BinOp->getRHS());
5441       DisableReplaceStmt = false;
5442       //
5443       // Unlike the main iterator, we explicily avoid changing 'BinOp'. If
5444       // we changed the RHS of BinOp, the rewriter would fail (since it needs
5445       // to see the original expression). Consider this example:
5446       //
5447       // Foo *obj1, *obj2;
5448       //
5449       // obj1.i = [obj2 rrrr];
5450       //
5451       // 'BinOp' for the previous expression looks like:
5452       //
5453       // (BinaryOperator 0x231ccf0 'int' '='
5454       //   (ObjCPropertyRefExpr 0x231cc70 'int' Kind=PropertyRef Property="i"
5455       //     (DeclRefExpr 0x231cc50 'Foo *' Var='obj1' 0x231cbb0))
5456       //   (ObjCMessageExpr 0x231ccb0 'int' selector=rrrr
5457       //     (DeclRefExpr 0x231cc90 'Foo *' Var='obj2' 0x231cbe0)))
5458       //
5459       // 'newStmt' represents the rewritten message expression. For example:
5460       //
5461       // (CallExpr 0x231d300 'id':'struct objc_object *'
5462       //   (ParenExpr 0x231d2e0 'int (*)(id, SEL)'
5463       //     (CStyleCastExpr 0x231d2c0 'int (*)(id, SEL)'
5464       //       (CStyleCastExpr 0x231d220 'void *'
5465       //         (DeclRefExpr 0x231d200 'id (id, SEL, ...)' FunctionDecl='objc_msgSend' 0x231cdc0))))
5466       //
5467       // Note that 'newStmt' is passed to RewritePropertySetter so that it
5468       // can be used as the setter argument. ReplaceStmt() will still 'see'
5469       // the original RHS (since we haven't altered BinOp).
5470       //
5471       // This implies the Rewrite* routines can no longer delete the original
5472       // node. As a result, we now leak the original AST nodes.
5473       //
5474       return RewritePropertySetter(BinOp, dyn_cast<Expr>(newStmt), SrcRange);
5475     } else {
5476       return RewritePropertyGetter(PropRefExpr);
5477     }
5478   }
5479   if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
5480     return RewriteAtSelector(AtSelector);
5481
5482   if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
5483     return RewriteObjCStringLiteral(AtString);
5484
5485   if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
5486 #if 0
5487     // Before we rewrite it, put the original message expression in a comment.
5488     SourceLocation startLoc = MessExpr->getLocStart();
5489     SourceLocation endLoc = MessExpr->getLocEnd();
5490
5491     const char *startBuf = SM->getCharacterData(startLoc);
5492     const char *endBuf = SM->getCharacterData(endLoc);
5493
5494     std::string messString;
5495     messString += "// ";
5496     messString.append(startBuf, endBuf-startBuf+1);
5497     messString += "\n";
5498
5499     // FIXME: Missing definition of
5500     // InsertText(clang::SourceLocation, char const*, unsigned int).
5501     // InsertText(startLoc, messString.c_str(), messString.size());
5502     // Tried this, but it didn't work either...
5503     // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
5504 #endif
5505     return RewriteMessageExpr(MessExpr);
5506   }
5507
5508   if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
5509     return RewriteObjCTryStmt(StmtTry);
5510
5511   if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
5512     return RewriteObjCSynchronizedStmt(StmtTry);
5513
5514   if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
5515     return RewriteObjCThrowStmt(StmtThrow);
5516
5517   if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
5518     return RewriteObjCProtocolExpr(ProtocolExp);
5519
5520   if (ObjCForCollectionStmt *StmtForCollection =
5521         dyn_cast<ObjCForCollectionStmt>(S))
5522     return RewriteObjCForCollectionStmt(StmtForCollection,
5523                                         OrigStmtRange.getEnd());
5524   if (BreakStmt *StmtBreakStmt =
5525       dyn_cast<BreakStmt>(S))
5526     return RewriteBreakStmt(StmtBreakStmt);
5527   if (ContinueStmt *StmtContinueStmt =
5528       dyn_cast<ContinueStmt>(S))
5529     return RewriteContinueStmt(StmtContinueStmt);
5530
5531   // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
5532   // and cast exprs.
5533   if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5534     // FIXME: What we're doing here is modifying the type-specifier that
5535     // precedes the first Decl.  In the future the DeclGroup should have
5536     // a separate type-specifier that we can rewrite.
5537     // NOTE: We need to avoid rewriting the DeclStmt if it is within
5538     // the context of an ObjCForCollectionStmt. For example:
5539     //   NSArray *someArray;
5540     //   for (id <FooProtocol> index in someArray) ;
5541     // This is because RewriteObjCForCollectionStmt() does textual rewriting 
5542     // and it depends on the original text locations/positions.
5543     if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
5544       RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin());
5545
5546     // Blocks rewrite rules.
5547     for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
5548          DI != DE; ++DI) {
5549       Decl *SD = *DI;
5550       if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5551         if (isTopLevelBlockPointerType(ND->getType()))
5552           RewriteBlockPointerDecl(ND);
5553         else if (ND->getType()->isFunctionPointerType())
5554           CheckFunctionPointerDecl(ND->getType(), ND);
5555         if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5556           if (VD->hasAttr<BlocksAttr>()) {
5557             static unsigned uniqueByrefDeclCount = 0;
5558             assert(!BlockByRefDeclNo.count(ND) &&
5559               "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5560             BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5561             RewriteByRefVar(VD);
5562           }
5563           else           
5564             RewriteTypeOfDecl(VD);
5565         }
5566       }
5567       if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
5568         if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5569           RewriteBlockPointerDecl(TD);
5570         else if (TD->getUnderlyingType()->isFunctionPointerType())
5571           CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5572       }
5573     }
5574   }
5575
5576   if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S))
5577     RewriteObjCQualifiedInterfaceTypes(CE);
5578
5579   if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5580       isa<DoStmt>(S) || isa<ForStmt>(S)) {
5581     assert(!Stmts.empty() && "Statement stack is empty");
5582     assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5583              isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5584             && "Statement stack mismatch");
5585     Stmts.pop_back();
5586   }
5587   // Handle blocks rewriting.
5588   if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
5589     if (BDRE->isByRef())
5590       return RewriteBlockDeclRefExpr(BDRE);
5591   }
5592   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5593     ValueDecl *VD = DRE->getDecl(); 
5594     if (VD->hasAttr<BlocksAttr>())
5595       return RewriteBlockDeclRefExpr(DRE);
5596     if (HasLocalVariableExternalStorage(VD))
5597       return RewriteLocalVariableExternalStorage(DRE);
5598   }
5599   
5600   if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
5601     if (CE->getCallee()->getType()->isBlockPointerType()) {
5602       Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
5603       ReplaceStmt(S, BlockCall);
5604       return BlockCall;
5605     }
5606   }
5607   if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) {
5608     RewriteCastExpr(CE);
5609   }
5610 #if 0
5611   if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
5612     CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), ICE->getSubExpr(), SourceLocation());
5613     // Get the new text.
5614     std::string SStr;
5615     llvm::raw_string_ostream Buf(SStr);
5616     Replacement->printPretty(Buf, *Context);
5617     const std::string &Str = Buf.str();
5618
5619     printf("CAST = %s\n", &Str[0]);
5620     InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
5621     delete S;
5622     return Replacement;
5623   }
5624 #endif
5625   // Return this stmt unmodified.
5626   return S;
5627 }
5628
5629 void RewriteObjC::RewriteRecordBody(RecordDecl *RD) {
5630   for (RecordDecl::field_iterator i = RD->field_begin(), 
5631                                   e = RD->field_end(); i != e; ++i) {
5632     FieldDecl *FD = *i;
5633     if (isTopLevelBlockPointerType(FD->getType()))
5634       RewriteBlockPointerDecl(FD);
5635     if (FD->getType()->isObjCQualifiedIdType() ||
5636         FD->getType()->isObjCQualifiedInterfaceType())
5637       RewriteObjCQualifiedInterfaceTypes(FD);
5638   }
5639 }
5640
5641 /// HandleDeclInMainFile - This is called for each top-level decl defined in the
5642 /// main file of the input.
5643 void RewriteObjC::HandleDeclInMainFile(Decl *D) {
5644   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
5645     if (FD->isOverloadedOperator())
5646       return;
5647
5648     // Since function prototypes don't have ParmDecl's, we check the function
5649     // prototype. This enables us to rewrite function declarations and
5650     // definitions using the same code.
5651     RewriteBlocksInFunctionProtoType(FD->getType(), FD);
5652
5653     // FIXME: If this should support Obj-C++, support CXXTryStmt
5654     if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
5655       CurFunctionDef = FD;
5656       CurFunctionDeclToDeclareForBlock = FD;
5657       CollectPropertySetters(Body);
5658       CurrentBody = Body;
5659       Body =
5660        cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5661       FD->setBody(Body);
5662       CurrentBody = 0;
5663       if (PropParentMap) {
5664         delete PropParentMap;
5665         PropParentMap = 0;
5666       }
5667       // This synthesizes and inserts the block "impl" struct, invoke function,
5668       // and any copy/dispose helper functions.
5669       InsertBlockLiteralsWithinFunction(FD);
5670       CurFunctionDef = 0;
5671       CurFunctionDeclToDeclareForBlock = 0;
5672     }
5673     return;
5674   }
5675   if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
5676     if (CompoundStmt *Body = MD->getCompoundBody()) {
5677       CurMethodDef = MD;
5678       CollectPropertySetters(Body);
5679       CurrentBody = Body;
5680       Body =
5681        cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5682       MD->setBody(Body);
5683       CurrentBody = 0;
5684       if (PropParentMap) {
5685         delete PropParentMap;
5686         PropParentMap = 0;
5687       }
5688       InsertBlockLiteralsWithinMethod(MD);
5689       CurMethodDef = 0;
5690     }
5691   }
5692   if (ObjCImplementationDecl *CI = dyn_cast<ObjCImplementationDecl>(D))
5693     ClassImplementation.push_back(CI);
5694   else if (ObjCCategoryImplDecl *CI = dyn_cast<ObjCCategoryImplDecl>(D))
5695     CategoryImplementation.push_back(CI);
5696   else if (ObjCClassDecl *CD = dyn_cast<ObjCClassDecl>(D))
5697     RewriteForwardClassDecl(CD);
5698   else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
5699     RewriteObjCQualifiedInterfaceTypes(VD);
5700     if (isTopLevelBlockPointerType(VD->getType()))
5701       RewriteBlockPointerDecl(VD);
5702     else if (VD->getType()->isFunctionPointerType()) {
5703       CheckFunctionPointerDecl(VD->getType(), VD);
5704       if (VD->getInit()) {
5705         if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
5706           RewriteCastExpr(CE);
5707         }
5708       }
5709     } else if (VD->getType()->isRecordType()) {
5710       RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl();
5711       if (RD->isDefinition())
5712         RewriteRecordBody(RD);
5713     }
5714     if (VD->getInit()) {
5715       GlobalVarDecl = VD;
5716       CollectPropertySetters(VD->getInit());
5717       CurrentBody = VD->getInit();
5718       RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
5719       CurrentBody = 0;
5720       if (PropParentMap) {
5721         delete PropParentMap;
5722         PropParentMap = 0;
5723       }
5724       SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(),
5725                               VD->getNameAsCString());
5726       GlobalVarDecl = 0;
5727
5728       // This is needed for blocks.
5729       if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
5730         RewriteCastExpr(CE);
5731       }
5732     }
5733     return;
5734   }
5735   if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
5736     if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5737       RewriteBlockPointerDecl(TD);
5738     else if (TD->getUnderlyingType()->isFunctionPointerType())
5739       CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5740     return;
5741   }
5742   if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
5743     if (RD->isDefinition()) 
5744       RewriteRecordBody(RD);
5745     return;
5746   }
5747   // Nothing yet.
5748 }
5749
5750 void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
5751   if (Diags.hasErrorOccurred())
5752     return;
5753
5754   RewriteInclude();
5755
5756   // Here's a great place to add any extra declarations that may be needed.
5757   // Write out meta data for each @protocol(<expr>).
5758   for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
5759        E = ProtocolExprDecls.end(); I != E; ++I)
5760     RewriteObjCProtocolMetaData(*I, "", "", Preamble);
5761
5762   InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
5763   if (ClassImplementation.size() || CategoryImplementation.size())
5764     RewriteImplementations();
5765
5766   // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
5767   // we are done.
5768   if (const RewriteBuffer *RewriteBuf =
5769       Rewrite.getRewriteBufferFor(MainFileID)) {
5770     //printf("Changed:\n");
5771     *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5772   } else {
5773     llvm::errs() << "No changes\n";
5774   }
5775
5776   if (ClassImplementation.size() || CategoryImplementation.size() ||
5777       ProtocolExprDecls.size()) {
5778     // Rewrite Objective-c meta data*
5779     std::string ResultStr;
5780     SynthesizeMetaDataIntoBuffer(ResultStr);
5781     // Emit metadata.
5782     *OutFile << ResultStr;
5783   }
5784   OutFile->flush();
5785 }