]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/lib/Rewrite/RewriteModernObjC.cpp
Partial MFC of r234508 (by adrian):
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / lib / Rewrite / RewriteModernObjC.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 RewriteModernObjC : public ASTConsumer {
35   protected:
36     
37     enum {
38       BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)),
39                                         block, ... */
40       BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
41       BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the 
42                                         __block variable */
43       BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy
44                                         helpers */
45       BLOCK_BYREF_CALLER      = 128, /* called from __block (byref) copy/dispose
46                                         support routines */
47       BLOCK_BYREF_CURRENT_MAX = 256
48     };
49     
50     enum {
51       BLOCK_NEEDS_FREE =        (1 << 24),
52       BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
53       BLOCK_HAS_CXX_OBJ =       (1 << 26),
54       BLOCK_IS_GC =             (1 << 27),
55       BLOCK_IS_GLOBAL =         (1 << 28),
56       BLOCK_HAS_DESCRIPTOR =    (1 << 29)
57     };
58     static const int OBJC_ABI_VERSION = 7;
59     
60     Rewriter Rewrite;
61     DiagnosticsEngine &Diags;
62     const LangOptions &LangOpts;
63     ASTContext *Context;
64     SourceManager *SM;
65     TranslationUnitDecl *TUDecl;
66     FileID MainFileID;
67     const char *MainFileStart, *MainFileEnd;
68     Stmt *CurrentBody;
69     ParentMap *PropParentMap; // created lazily.
70     std::string InFileName;
71     raw_ostream* OutFile;
72     std::string Preamble;
73     
74     TypeDecl *ProtocolTypeDecl;
75     VarDecl *GlobalVarDecl;
76     Expr *GlobalConstructionExp;
77     unsigned RewriteFailedDiag;
78     unsigned GlobalBlockRewriteFailedDiag;
79     // ObjC string constant support.
80     unsigned NumObjCStringLiterals;
81     VarDecl *ConstantStringClassReference;
82     RecordDecl *NSStringRecord;
83
84     // ObjC foreach break/continue generation support.
85     int BcLabelCount;
86     
87     unsigned TryFinallyContainsReturnDiag;
88     // Needed for super.
89     ObjCMethodDecl *CurMethodDef;
90     RecordDecl *SuperStructDecl;
91     RecordDecl *ConstantStringDecl;
92     
93     FunctionDecl *MsgSendFunctionDecl;
94     FunctionDecl *MsgSendSuperFunctionDecl;
95     FunctionDecl *MsgSendStretFunctionDecl;
96     FunctionDecl *MsgSendSuperStretFunctionDecl;
97     FunctionDecl *MsgSendFpretFunctionDecl;
98     FunctionDecl *GetClassFunctionDecl;
99     FunctionDecl *GetMetaClassFunctionDecl;
100     FunctionDecl *GetSuperClassFunctionDecl;
101     FunctionDecl *SelGetUidFunctionDecl;
102     FunctionDecl *CFStringFunctionDecl;
103     FunctionDecl *SuperContructorFunctionDecl;
104     FunctionDecl *CurFunctionDef;
105     FunctionDecl *CurFunctionDeclToDeclareForBlock;
106
107     /* Misc. containers needed for meta-data rewrite. */
108     SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
109     SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
110     llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
111     llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
112     llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
113     llvm::SmallPtrSet<TagDecl*, 8> TagsDefinedInIvarDecls;
114     SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
115     /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
116     SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses;
117     
118     /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
119     llvm::SmallVector<ObjCCategoryDecl*, 8> DefinedNonLazyCategories;
120     
121     SmallVector<Stmt *, 32> Stmts;
122     SmallVector<int, 8> ObjCBcLabelNo;
123     // Remember all the @protocol(<expr>) expressions.
124     llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
125     
126     llvm::DenseSet<uint64_t> CopyDestroyCache;
127
128     // Block expressions.
129     SmallVector<BlockExpr *, 32> Blocks;
130     SmallVector<int, 32> InnerDeclRefsCount;
131     SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
132     
133     SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
134
135     // Block related declarations.
136     SmallVector<ValueDecl *, 8> BlockByCopyDecls;
137     llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
138     SmallVector<ValueDecl *, 8> BlockByRefDecls;
139     llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
140     llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
141     llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
142     llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
143     
144     llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
145     llvm::DenseMap<ObjCInterfaceDecl *, 
146                     llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars;
147     
148     // This maps an original source AST to it's rewritten form. This allows
149     // us to avoid rewriting the same node twice (which is very uncommon).
150     // This is needed to support some of the exotic property rewriting.
151     llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
152
153     // Needed for header files being rewritten
154     bool IsHeader;
155     bool SilenceRewriteMacroWarning;
156     bool objc_impl_method;
157     
158     bool DisableReplaceStmt;
159     class DisableReplaceStmtScope {
160       RewriteModernObjC &R;
161       bool SavedValue;
162     
163     public:
164       DisableReplaceStmtScope(RewriteModernObjC &R)
165         : R(R), SavedValue(R.DisableReplaceStmt) {
166         R.DisableReplaceStmt = true;
167       }
168       ~DisableReplaceStmtScope() {
169         R.DisableReplaceStmt = SavedValue;
170       }
171     };
172     void InitializeCommon(ASTContext &context);
173
174   public:
175     llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
176     // Top Level Driver code.
177     virtual bool HandleTopLevelDecl(DeclGroupRef D) {
178       for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
179         if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
180           if (!Class->isThisDeclarationADefinition()) {
181             RewriteForwardClassDecl(D);
182             break;
183           } else {
184             // Keep track of all interface declarations seen.
185             ObjCInterfacesSeen.push_back(Class);
186             break;
187           }
188         }
189
190         if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) {
191           if (!Proto->isThisDeclarationADefinition()) {
192             RewriteForwardProtocolDecl(D);
193             break;
194           }
195         }
196
197         HandleTopLevelSingleDecl(*I);
198       }
199       return true;
200     }
201     void HandleTopLevelSingleDecl(Decl *D);
202     void HandleDeclInMainFile(Decl *D);
203     RewriteModernObjC(std::string inFile, raw_ostream *OS,
204                 DiagnosticsEngine &D, const LangOptions &LOpts,
205                 bool silenceMacroWarn);
206     
207     ~RewriteModernObjC() {}
208     
209     virtual void HandleTranslationUnit(ASTContext &C);
210
211     void ReplaceStmt(Stmt *Old, Stmt *New) {
212       Stmt *ReplacingStmt = ReplacedNodes[Old];
213
214       if (ReplacingStmt)
215         return; // We can't rewrite the same node twice.
216
217       if (DisableReplaceStmt)
218         return;
219
220       // If replacement succeeded or warning disabled return with no warning.
221       if (!Rewrite.ReplaceStmt(Old, New)) {
222         ReplacedNodes[Old] = New;
223         return;
224       }
225       if (SilenceRewriteMacroWarning)
226         return;
227       Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
228                    << Old->getSourceRange();
229     }
230
231     void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
232       if (DisableReplaceStmt)
233         return;
234
235       // Measure the old text.
236       int Size = Rewrite.getRangeSize(SrcRange);
237       if (Size == -1) {
238         Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
239                      << Old->getSourceRange();
240         return;
241       }
242       // Get the new text.
243       std::string SStr;
244       llvm::raw_string_ostream S(SStr);
245       New->printPretty(S, *Context, 0, PrintingPolicy(LangOpts));
246       const std::string &Str = S.str();
247
248       // If replacement succeeded or warning disabled return with no warning.
249       if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
250         ReplacedNodes[Old] = New;
251         return;
252       }
253       if (SilenceRewriteMacroWarning)
254         return;
255       Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
256                    << Old->getSourceRange();
257     }
258
259     void InsertText(SourceLocation Loc, StringRef Str,
260                     bool InsertAfter = true) {
261       // If insertion succeeded or warning disabled return with no warning.
262       if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
263           SilenceRewriteMacroWarning)
264         return;
265
266       Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
267     }
268
269     void ReplaceText(SourceLocation Start, unsigned OrigLength,
270                      StringRef Str) {
271       // If removal succeeded or warning disabled return with no warning.
272       if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
273           SilenceRewriteMacroWarning)
274         return;
275
276       Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
277     }
278
279     // Syntactic Rewriting.
280     void RewriteRecordBody(RecordDecl *RD);
281     void RewriteInclude();
282     void RewriteForwardClassDecl(DeclGroupRef D);
283     void RewriteForwardClassDecl(const llvm::SmallVector<Decl*, 8> &DG);
284     void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 
285                                      const std::string &typedefString);
286     void RewriteImplementations();
287     void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
288                                  ObjCImplementationDecl *IMD,
289                                  ObjCCategoryImplDecl *CID);
290     void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
291     void RewriteImplementationDecl(Decl *Dcl);
292     void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
293                                ObjCMethodDecl *MDecl, std::string &ResultStr);
294     void RewriteTypeIntoString(QualType T, std::string &ResultStr,
295                                const FunctionType *&FPRetType);
296     void RewriteByRefString(std::string &ResultStr, const std::string &Name,
297                             ValueDecl *VD, bool def=false);
298     void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
299     void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
300     void RewriteForwardProtocolDecl(DeclGroupRef D);
301     void RewriteForwardProtocolDecl(const llvm::SmallVector<Decl*, 8> &DG);
302     void RewriteMethodDeclaration(ObjCMethodDecl *Method);
303     void RewriteProperty(ObjCPropertyDecl *prop);
304     void RewriteFunctionDecl(FunctionDecl *FD);
305     void RewriteBlockPointerType(std::string& Str, QualType Type);
306     void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
307     void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
308     void RewriteTypeOfDecl(VarDecl *VD);
309     void RewriteObjCQualifiedInterfaceTypes(Expr *E);
310   
311     // Expression Rewriting.
312     Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
313     Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
314     Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo);
315     Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo);
316     Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
317     Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
318     Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
319     Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp);
320     Stmt *RewriteObjCNumericLiteralExpr(ObjCNumericLiteral *Exp);
321     Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp);
322     Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp);
323     Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
324     Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
325     Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
326     Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
327     Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
328                                        SourceLocation OrigEnd);
329     Stmt *RewriteBreakStmt(BreakStmt *S);
330     Stmt *RewriteContinueStmt(ContinueStmt *S);
331     void RewriteCastExpr(CStyleCastExpr *CE);
332     void RewriteImplicitCastObjCExpr(CastExpr *IE);
333     void RewriteLinkageSpec(LinkageSpecDecl *LSD);
334     
335     // Block rewriting.
336     void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
337     
338     // Block specific rewrite rules.
339     void RewriteBlockPointerDecl(NamedDecl *VD);
340     void RewriteByRefVar(VarDecl *VD);
341     Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
342     Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
343     void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
344     
345     void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
346                                       std::string &Result);
347     
348     void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result);
349     
350     bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result);
351     
352     void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
353                                   std::string &Result);
354     
355     virtual void Initialize(ASTContext &context);
356     
357     // Misc. AST transformation routines. Somtimes they end up calling
358     // rewriting routines on the new ASTs.
359     CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
360                                            Expr **args, unsigned nargs,
361                                            SourceLocation StartLoc=SourceLocation(),
362                                            SourceLocation EndLoc=SourceLocation());
363
364     Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
365                            SourceLocation StartLoc=SourceLocation(),
366                            SourceLocation EndLoc=SourceLocation());
367     
368     void SynthCountByEnumWithState(std::string &buf);
369     void SynthMsgSendFunctionDecl();
370     void SynthMsgSendSuperFunctionDecl();
371     void SynthMsgSendStretFunctionDecl();
372     void SynthMsgSendFpretFunctionDecl();
373     void SynthMsgSendSuperStretFunctionDecl();
374     void SynthGetClassFunctionDecl();
375     void SynthGetMetaClassFunctionDecl();
376     void SynthGetSuperClassFunctionDecl();
377     void SynthSelGetUidFunctionDecl();
378     void SynthSuperContructorFunctionDecl();
379     
380     // Rewriting metadata
381     template<typename MethodIterator>
382     void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
383                                     MethodIterator MethodEnd,
384                                     bool IsInstanceMethod,
385                                     StringRef prefix,
386                                     StringRef ClassName,
387                                     std::string &Result);
388     void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
389                                      std::string &Result);
390     virtual void RewriteObjCProtocolListMetaData(
391                    const ObjCList<ObjCProtocolDecl> &Prots,
392                    StringRef prefix, StringRef ClassName, std::string &Result);
393     virtual void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
394                                           std::string &Result);
395     virtual void RewriteClassSetupInitHook(std::string &Result);
396     
397     virtual void RewriteMetaDataIntoBuffer(std::string &Result);
398     virtual void WriteImageInfo(std::string &Result);
399     virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
400                                              std::string &Result);
401     virtual void RewriteCategorySetupInitHook(std::string &Result);
402     
403     // Rewriting ivar
404     virtual void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
405                                               std::string &Result);
406     virtual Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV);
407
408     
409     std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag);
410     std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
411                                       StringRef funcName, std::string Tag);
412     std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
413                                       StringRef funcName, std::string Tag);
414     std::string SynthesizeBlockImpl(BlockExpr *CE, 
415                                     std::string Tag, std::string Desc);
416     std::string SynthesizeBlockDescriptor(std::string DescTag, 
417                                           std::string ImplTag,
418                                           int i, StringRef funcName,
419                                           unsigned hasCopy);
420     Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
421     void SynthesizeBlockLiterals(SourceLocation FunLocStart,
422                                  StringRef FunName);
423     FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
424     Stmt *SynthBlockInitExpr(BlockExpr *Exp,
425             const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs);
426
427     // Misc. helper routines.
428     QualType getProtocolType();
429     void WarnAboutReturnGotoStmts(Stmt *S);
430     void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
431     void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
432     void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
433
434     bool IsDeclStmtInForeachHeader(DeclStmt *DS);
435     void CollectBlockDeclRefInfo(BlockExpr *Exp);
436     void GetBlockDeclRefExprs(Stmt *S);
437     void GetInnerBlockDeclRefExprs(Stmt *S, 
438                 SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs,
439                 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
440
441     // We avoid calling Type::isBlockPointerType(), since it operates on the
442     // canonical type. We only care if the top-level type is a closure pointer.
443     bool isTopLevelBlockPointerType(QualType T) {
444       return isa<BlockPointerType>(T);
445     }
446
447     /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
448     /// to a function pointer type and upon success, returns true; false
449     /// otherwise.
450     bool convertBlockPointerToFunctionPointer(QualType &T) {
451       if (isTopLevelBlockPointerType(T)) {
452         const BlockPointerType *BPT = T->getAs<BlockPointerType>();
453         T = Context->getPointerType(BPT->getPointeeType());
454         return true;
455       }
456       return false;
457     }
458     
459     bool convertObjCTypeToCStyleType(QualType &T);
460     
461     bool needToScanForQualifiers(QualType T);
462     QualType getSuperStructType();
463     QualType getConstantStringStructType();
464     QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
465     bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
466     
467     void convertToUnqualifiedObjCType(QualType &T) {
468       if (T->isObjCQualifiedIdType()) {
469         bool isConst = T.isConstQualified();
470         T = isConst ? Context->getObjCIdType().withConst() 
471                     : Context->getObjCIdType();
472       }
473       else if (T->isObjCQualifiedClassType())
474         T = Context->getObjCClassType();
475       else if (T->isObjCObjectPointerType() &&
476                T->getPointeeType()->isObjCQualifiedInterfaceType()) {
477         if (const ObjCObjectPointerType * OBJPT =
478               T->getAsObjCInterfacePointerType()) {
479           const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
480           T = QualType(IFaceT, 0);
481           T = Context->getPointerType(T);
482         }
483      }
484     }
485     
486     // FIXME: This predicate seems like it would be useful to add to ASTContext.
487     bool isObjCType(QualType T) {
488       if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
489         return false;
490
491       QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
492
493       if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
494           OCT == Context->getCanonicalType(Context->getObjCClassType()))
495         return true;
496
497       if (const PointerType *PT = OCT->getAs<PointerType>()) {
498         if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
499             PT->getPointeeType()->isObjCQualifiedIdType())
500           return true;
501       }
502       return false;
503     }
504     bool PointerTypeTakesAnyBlockArguments(QualType QT);
505     bool PointerTypeTakesAnyObjCQualifiedType(QualType QT);
506     void GetExtentOfArgList(const char *Name, const char *&LParen,
507                             const char *&RParen);
508     
509     void QuoteDoublequotes(std::string &From, std::string &To) {
510       for (unsigned i = 0; i < From.length(); i++) {
511         if (From[i] == '"')
512           To += "\\\"";
513         else
514           To += From[i];
515       }
516     }
517
518     QualType getSimpleFunctionType(QualType result,
519                                    const QualType *args,
520                                    unsigned numArgs,
521                                    bool variadic = false) {
522       if (result == Context->getObjCInstanceType())
523         result =  Context->getObjCIdType();
524       FunctionProtoType::ExtProtoInfo fpi;
525       fpi.Variadic = variadic;
526       return Context->getFunctionType(result, args, numArgs, fpi);
527     }
528
529     // Helper function: create a CStyleCastExpr with trivial type source info.
530     CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
531                                              CastKind Kind, Expr *E) {
532       TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
533       return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, 0, TInfo,
534                                     SourceLocation(), SourceLocation());
535     }
536     
537     bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
538       IdentifierInfo* II = &Context->Idents.get("load");
539       Selector LoadSel = Context->Selectors.getSelector(0, &II);
540       return OD->getClassMethod(LoadSel) != 0;
541     }
542   };
543   
544 }
545
546 void RewriteModernObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
547                                                    NamedDecl *D) {
548   if (const FunctionProtoType *fproto
549       = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) {
550     for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(),
551          E = fproto->arg_type_end(); I && (I != E); ++I)
552       if (isTopLevelBlockPointerType(*I)) {
553         // All the args are checked/rewritten. Don't call twice!
554         RewriteBlockPointerDecl(D);
555         break;
556       }
557   }
558 }
559
560 void RewriteModernObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
561   const PointerType *PT = funcType->getAs<PointerType>();
562   if (PT && PointerTypeTakesAnyBlockArguments(funcType))
563     RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
564 }
565
566 static bool IsHeaderFile(const std::string &Filename) {
567   std::string::size_type DotPos = Filename.rfind('.');
568
569   if (DotPos == std::string::npos) {
570     // no file extension
571     return false;
572   }
573
574   std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
575   // C header: .h
576   // C++ header: .hh or .H;
577   return Ext == "h" || Ext == "hh" || Ext == "H";
578 }
579
580 RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS,
581                          DiagnosticsEngine &D, const LangOptions &LOpts,
582                          bool silenceMacroWarn)
583       : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
584         SilenceRewriteMacroWarning(silenceMacroWarn) {
585   IsHeader = IsHeaderFile(inFile);
586   RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
587                "rewriting sub-expression within a macro (may not be correct)");
588   // FIXME. This should be an error. But if block is not called, it is OK. And it
589   // may break including some headers.
590   GlobalBlockRewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
591     "rewriting block literal declared in global scope is not implemented");
592           
593   TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
594                DiagnosticsEngine::Warning,
595                "rewriter doesn't support user-specified control flow semantics "
596                "for @try/@finally (code may not execute properly)");
597 }
598
599 ASTConsumer *clang::CreateModernObjCRewriter(const std::string& InFile,
600                                        raw_ostream* OS,
601                                        DiagnosticsEngine &Diags,
602                                        const LangOptions &LOpts,
603                                        bool SilenceRewriteMacroWarning) {
604     return new RewriteModernObjC(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning);
605 }
606
607 void RewriteModernObjC::InitializeCommon(ASTContext &context) {
608   Context = &context;
609   SM = &Context->getSourceManager();
610   TUDecl = Context->getTranslationUnitDecl();
611   MsgSendFunctionDecl = 0;
612   MsgSendSuperFunctionDecl = 0;
613   MsgSendStretFunctionDecl = 0;
614   MsgSendSuperStretFunctionDecl = 0;
615   MsgSendFpretFunctionDecl = 0;
616   GetClassFunctionDecl = 0;
617   GetMetaClassFunctionDecl = 0;
618   GetSuperClassFunctionDecl = 0;
619   SelGetUidFunctionDecl = 0;
620   CFStringFunctionDecl = 0;
621   ConstantStringClassReference = 0;
622   NSStringRecord = 0;
623   CurMethodDef = 0;
624   CurFunctionDef = 0;
625   CurFunctionDeclToDeclareForBlock = 0;
626   GlobalVarDecl = 0;
627   GlobalConstructionExp = 0;
628   SuperStructDecl = 0;
629   ProtocolTypeDecl = 0;
630   ConstantStringDecl = 0;
631   BcLabelCount = 0;
632   SuperContructorFunctionDecl = 0;
633   NumObjCStringLiterals = 0;
634   PropParentMap = 0;
635   CurrentBody = 0;
636   DisableReplaceStmt = false;
637   objc_impl_method = false;
638
639   // Get the ID and start/end of the main file.
640   MainFileID = SM->getMainFileID();
641   const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
642   MainFileStart = MainBuf->getBufferStart();
643   MainFileEnd = MainBuf->getBufferEnd();
644
645   Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
646 }
647
648 //===----------------------------------------------------------------------===//
649 // Top Level Driver Code
650 //===----------------------------------------------------------------------===//
651
652 void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) {
653   if (Diags.hasErrorOccurred())
654     return;
655
656   // Two cases: either the decl could be in the main file, or it could be in a
657   // #included file.  If the former, rewrite it now.  If the later, check to see
658   // if we rewrote the #include/#import.
659   SourceLocation Loc = D->getLocation();
660   Loc = SM->getExpansionLoc(Loc);
661
662   // If this is for a builtin, ignore it.
663   if (Loc.isInvalid()) return;
664
665   // Look for built-in declarations that we need to refer during the rewrite.
666   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
667     RewriteFunctionDecl(FD);
668   } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
669     // declared in <Foundation/NSString.h>
670     if (FVD->getName() == "_NSConstantStringClassReference") {
671       ConstantStringClassReference = FVD;
672       return;
673     }
674   } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
675     RewriteCategoryDecl(CD);
676   } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
677     if (PD->isThisDeclarationADefinition())
678       RewriteProtocolDecl(PD);
679   } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
680     // FIXME. This will not work in all situations and leaving it out
681     // is harmless.
682     // RewriteLinkageSpec(LSD);
683     
684     // Recurse into linkage specifications
685     for (DeclContext::decl_iterator DI = LSD->decls_begin(),
686                                  DIEnd = LSD->decls_end();
687          DI != DIEnd; ) {
688       if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
689         if (!IFace->isThisDeclarationADefinition()) {
690           SmallVector<Decl *, 8> DG;
691           SourceLocation StartLoc = IFace->getLocStart();
692           do {
693             if (isa<ObjCInterfaceDecl>(*DI) &&
694                 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
695                 StartLoc == (*DI)->getLocStart())
696               DG.push_back(*DI);
697             else
698               break;
699             
700             ++DI;
701           } while (DI != DIEnd);
702           RewriteForwardClassDecl(DG);
703           continue;
704         }
705         else {
706           // Keep track of all interface declarations seen.
707           ObjCInterfacesSeen.push_back(IFace);
708           ++DI;
709           continue;
710         }
711       }
712
713       if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) {
714         if (!Proto->isThisDeclarationADefinition()) {
715           SmallVector<Decl *, 8> DG;
716           SourceLocation StartLoc = Proto->getLocStart();
717           do {
718             if (isa<ObjCProtocolDecl>(*DI) &&
719                 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
720                 StartLoc == (*DI)->getLocStart())
721               DG.push_back(*DI);
722             else
723               break;
724             
725             ++DI;
726           } while (DI != DIEnd);
727           RewriteForwardProtocolDecl(DG);
728           continue;
729         }
730       }
731       
732       HandleTopLevelSingleDecl(*DI);
733       ++DI;
734     }
735   }
736   // If we have a decl in the main file, see if we should rewrite it.
737   if (SM->isFromMainFile(Loc))
738     return HandleDeclInMainFile(D);
739 }
740
741 //===----------------------------------------------------------------------===//
742 // Syntactic (non-AST) Rewriting Code
743 //===----------------------------------------------------------------------===//
744
745 void RewriteModernObjC::RewriteInclude() {
746   SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
747   StringRef MainBuf = SM->getBufferData(MainFileID);
748   const char *MainBufStart = MainBuf.begin();
749   const char *MainBufEnd = MainBuf.end();
750   size_t ImportLen = strlen("import");
751
752   // Loop over the whole file, looking for includes.
753   for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
754     if (*BufPtr == '#') {
755       if (++BufPtr == MainBufEnd)
756         return;
757       while (*BufPtr == ' ' || *BufPtr == '\t')
758         if (++BufPtr == MainBufEnd)
759           return;
760       if (!strncmp(BufPtr, "import", ImportLen)) {
761         // replace import with include
762         SourceLocation ImportLoc =
763           LocStart.getLocWithOffset(BufPtr-MainBufStart);
764         ReplaceText(ImportLoc, ImportLen, "include");
765         BufPtr += ImportLen;
766       }
767     }
768   }
769 }
770
771 static std::string getIvarAccessString(ObjCIvarDecl *OID) {
772   const ObjCInterfaceDecl *ClassDecl = OID->getContainingInterface();
773   std::string S;
774   S = "((struct ";
775   S += ClassDecl->getIdentifier()->getName();
776   S += "_IMPL *)self)->";
777   S += OID->getName();
778   return S;
779 }
780
781 void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
782                                           ObjCImplementationDecl *IMD,
783                                           ObjCCategoryImplDecl *CID) {
784   static bool objcGetPropertyDefined = false;
785   static bool objcSetPropertyDefined = false;
786   SourceLocation startLoc = PID->getLocStart();
787   InsertText(startLoc, "// ");
788   const char *startBuf = SM->getCharacterData(startLoc);
789   assert((*startBuf == '@') && "bogus @synthesize location");
790   const char *semiBuf = strchr(startBuf, ';');
791   assert((*semiBuf == ';') && "@synthesize: can't find ';'");
792   SourceLocation onePastSemiLoc =
793     startLoc.getLocWithOffset(semiBuf-startBuf+1);
794
795   if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
796     return; // FIXME: is this correct?
797
798   // Generate the 'getter' function.
799   ObjCPropertyDecl *PD = PID->getPropertyDecl();
800   ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
801
802   if (!OID)
803     return;
804   unsigned Attributes = PD->getPropertyAttributes();
805   if (!PD->getGetterMethodDecl()->isDefined()) {
806     bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
807                           (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
808                                          ObjCPropertyDecl::OBJC_PR_copy));
809     std::string Getr;
810     if (GenGetProperty && !objcGetPropertyDefined) {
811       objcGetPropertyDefined = true;
812       // FIXME. Is this attribute correct in all cases?
813       Getr = "\nextern \"C\" __declspec(dllimport) "
814             "id objc_getProperty(id, SEL, long, bool);\n";
815     }
816     RewriteObjCMethodDecl(OID->getContainingInterface(),  
817                           PD->getGetterMethodDecl(), Getr);
818     Getr += "{ ";
819     // Synthesize an explicit cast to gain access to the ivar.
820     // See objc-act.c:objc_synthesize_new_getter() for details.
821     if (GenGetProperty) {
822       // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
823       Getr += "typedef ";
824       const FunctionType *FPRetType = 0;
825       RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr, 
826                             FPRetType);
827       Getr += " _TYPE";
828       if (FPRetType) {
829         Getr += ")"; // close the precedence "scope" for "*".
830       
831         // Now, emit the argument types (if any).
832         if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){
833           Getr += "(";
834           for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
835             if (i) Getr += ", ";
836             std::string ParamStr = FT->getArgType(i).getAsString(
837                                                           Context->getPrintingPolicy());
838             Getr += ParamStr;
839           }
840           if (FT->isVariadic()) {
841             if (FT->getNumArgs()) Getr += ", ";
842             Getr += "...";
843           }
844           Getr += ")";
845         } else
846           Getr += "()";
847       }
848       Getr += ";\n";
849       Getr += "return (_TYPE)";
850       Getr += "objc_getProperty(self, _cmd, ";
851       RewriteIvarOffsetComputation(OID, Getr);
852       Getr += ", 1)";
853     }
854     else
855       Getr += "return " + getIvarAccessString(OID);
856     Getr += "; }";
857     InsertText(onePastSemiLoc, Getr);
858   }
859   
860   if (PD->isReadOnly() || PD->getSetterMethodDecl()->isDefined())
861     return;
862
863   // Generate the 'setter' function.
864   std::string Setr;
865   bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
866                                       ObjCPropertyDecl::OBJC_PR_copy);
867   if (GenSetProperty && !objcSetPropertyDefined) {
868     objcSetPropertyDefined = true;
869     // FIXME. Is this attribute correct in all cases?
870     Setr = "\nextern \"C\" __declspec(dllimport) "
871     "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
872   }
873   
874   RewriteObjCMethodDecl(OID->getContainingInterface(), 
875                         PD->getSetterMethodDecl(), Setr);
876   Setr += "{ ";
877   // Synthesize an explicit cast to initialize the ivar.
878   // See objc-act.c:objc_synthesize_new_setter() for details.
879   if (GenSetProperty) {
880     Setr += "objc_setProperty (self, _cmd, ";
881     RewriteIvarOffsetComputation(OID, Setr);
882     Setr += ", (id)";
883     Setr += PD->getName();
884     Setr += ", ";
885     if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
886       Setr += "0, ";
887     else
888       Setr += "1, ";
889     if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
890       Setr += "1)";
891     else
892       Setr += "0)";
893   }
894   else {
895     Setr += getIvarAccessString(OID) + " = ";
896     Setr += PD->getName();
897   }
898   Setr += "; }";
899   InsertText(onePastSemiLoc, Setr);
900 }
901
902 static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
903                                        std::string &typedefString) {
904   typedefString += "#ifndef _REWRITER_typedef_";
905   typedefString += ForwardDecl->getNameAsString();
906   typedefString += "\n";
907   typedefString += "#define _REWRITER_typedef_";
908   typedefString += ForwardDecl->getNameAsString();
909   typedefString += "\n";
910   typedefString += "typedef struct objc_object ";
911   typedefString += ForwardDecl->getNameAsString();
912   // typedef struct { } _objc_exc_Classname;
913   typedefString += ";\ntypedef struct {} _objc_exc_";
914   typedefString += ForwardDecl->getNameAsString();
915   typedefString += ";\n#endif\n";
916 }
917
918 void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
919                                               const std::string &typedefString) {
920     SourceLocation startLoc = ClassDecl->getLocStart();
921     const char *startBuf = SM->getCharacterData(startLoc);
922     const char *semiPtr = strchr(startBuf, ';'); 
923     // Replace the @class with typedefs corresponding to the classes.
924     ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);  
925 }
926
927 void RewriteModernObjC::RewriteForwardClassDecl(DeclGroupRef D) {
928   std::string typedefString;
929   for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
930     ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(*I);
931     if (I == D.begin()) {
932       // Translate to typedef's that forward reference structs with the same name
933       // as the class. As a convenience, we include the original declaration
934       // as a comment.
935       typedefString += "// @class ";
936       typedefString += ForwardDecl->getNameAsString();
937       typedefString += ";\n";
938     }
939     RewriteOneForwardClassDecl(ForwardDecl, typedefString);
940   }
941   DeclGroupRef::iterator I = D.begin();
942   RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
943 }
944
945 void RewriteModernObjC::RewriteForwardClassDecl(
946                                 const llvm::SmallVector<Decl*, 8> &D) {
947   std::string typedefString;
948   for (unsigned i = 0; i < D.size(); i++) {
949     ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]);
950     if (i == 0) {
951       typedefString += "// @class ";
952       typedefString += ForwardDecl->getNameAsString();
953       typedefString += ";\n";
954     }
955     RewriteOneForwardClassDecl(ForwardDecl, typedefString);
956   }
957   RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
958 }
959
960 void RewriteModernObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
961   // When method is a synthesized one, such as a getter/setter there is
962   // nothing to rewrite.
963   if (Method->isImplicit())
964     return;
965   SourceLocation LocStart = Method->getLocStart();
966   SourceLocation LocEnd = Method->getLocEnd();
967
968   if (SM->getExpansionLineNumber(LocEnd) >
969       SM->getExpansionLineNumber(LocStart)) {
970     InsertText(LocStart, "#if 0\n");
971     ReplaceText(LocEnd, 1, ";\n#endif\n");
972   } else {
973     InsertText(LocStart, "// ");
974   }
975 }
976
977 void RewriteModernObjC::RewriteProperty(ObjCPropertyDecl *prop) {
978   SourceLocation Loc = prop->getAtLoc();
979
980   ReplaceText(Loc, 0, "// ");
981   // FIXME: handle properties that are declared across multiple lines.
982 }
983
984 void RewriteModernObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
985   SourceLocation LocStart = CatDecl->getLocStart();
986
987   // FIXME: handle category headers that are declared across multiple lines.
988   ReplaceText(LocStart, 0, "// ");
989   if (CatDecl->getIvarLBraceLoc().isValid())
990     InsertText(CatDecl->getIvarLBraceLoc(), "// ");
991   for (ObjCCategoryDecl::ivar_iterator
992        I = CatDecl->ivar_begin(), E = CatDecl->ivar_end(); I != E; ++I) {
993     ObjCIvarDecl *Ivar = (*I);
994     SourceLocation LocStart = Ivar->getLocStart();
995     ReplaceText(LocStart, 0, "// ");
996   } 
997   if (CatDecl->getIvarRBraceLoc().isValid())
998     InsertText(CatDecl->getIvarRBraceLoc(), "// ");
999   
1000   for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(),
1001        E = CatDecl->prop_end(); I != E; ++I)
1002     RewriteProperty(*I);
1003   
1004   for (ObjCCategoryDecl::instmeth_iterator
1005          I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
1006        I != E; ++I)
1007     RewriteMethodDeclaration(*I);
1008   for (ObjCCategoryDecl::classmeth_iterator
1009          I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
1010        I != E; ++I)
1011     RewriteMethodDeclaration(*I);
1012
1013   // Lastly, comment out the @end.
1014   ReplaceText(CatDecl->getAtEndRange().getBegin(), 
1015               strlen("@end"), "/* @end */");
1016 }
1017
1018 void RewriteModernObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
1019   SourceLocation LocStart = PDecl->getLocStart();
1020   assert(PDecl->isThisDeclarationADefinition());
1021   
1022   // FIXME: handle protocol headers that are declared across multiple lines.
1023   ReplaceText(LocStart, 0, "// ");
1024
1025   for (ObjCProtocolDecl::instmeth_iterator
1026          I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
1027        I != E; ++I)
1028     RewriteMethodDeclaration(*I);
1029   for (ObjCProtocolDecl::classmeth_iterator
1030          I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
1031        I != E; ++I)
1032     RewriteMethodDeclaration(*I);
1033
1034   for (ObjCInterfaceDecl::prop_iterator I = PDecl->prop_begin(),
1035        E = PDecl->prop_end(); I != E; ++I)
1036     RewriteProperty(*I);
1037   
1038   // Lastly, comment out the @end.
1039   SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
1040   ReplaceText(LocEnd, strlen("@end"), "/* @end */");
1041
1042   // Must comment out @optional/@required
1043   const char *startBuf = SM->getCharacterData(LocStart);
1044   const char *endBuf = SM->getCharacterData(LocEnd);
1045   for (const char *p = startBuf; p < endBuf; p++) {
1046     if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
1047       SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
1048       ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
1049
1050     }
1051     else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
1052       SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
1053       ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
1054
1055     }
1056   }
1057 }
1058
1059 void RewriteModernObjC::RewriteForwardProtocolDecl(DeclGroupRef D) {
1060   SourceLocation LocStart = (*D.begin())->getLocStart();
1061   if (LocStart.isInvalid())
1062     llvm_unreachable("Invalid SourceLocation");
1063   // FIXME: handle forward protocol that are declared across multiple lines.
1064   ReplaceText(LocStart, 0, "// ");
1065 }
1066
1067 void 
1068 RewriteModernObjC::RewriteForwardProtocolDecl(const llvm::SmallVector<Decl*, 8> &DG) {
1069   SourceLocation LocStart = DG[0]->getLocStart();
1070   if (LocStart.isInvalid())
1071     llvm_unreachable("Invalid SourceLocation");
1072   // FIXME: handle forward protocol that are declared across multiple lines.
1073   ReplaceText(LocStart, 0, "// ");
1074 }
1075
1076 void 
1077 RewriteModernObjC::RewriteLinkageSpec(LinkageSpecDecl *LSD) {
1078   SourceLocation LocStart = LSD->getExternLoc();
1079   if (LocStart.isInvalid())
1080     llvm_unreachable("Invalid extern SourceLocation");
1081   
1082   ReplaceText(LocStart, 0, "// ");
1083   if (!LSD->hasBraces())
1084     return;
1085   // FIXME. We don't rewrite well if '{' is not on same line as 'extern'.
1086   SourceLocation LocRBrace = LSD->getRBraceLoc();
1087   if (LocRBrace.isInvalid())
1088     llvm_unreachable("Invalid rbrace SourceLocation");
1089   ReplaceText(LocRBrace, 0, "// ");
1090 }
1091
1092 void RewriteModernObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
1093                                         const FunctionType *&FPRetType) {
1094   if (T->isObjCQualifiedIdType())
1095     ResultStr += "id";
1096   else if (T->isFunctionPointerType() ||
1097            T->isBlockPointerType()) {
1098     // needs special handling, since pointer-to-functions have special
1099     // syntax (where a decaration models use).
1100     QualType retType = T;
1101     QualType PointeeTy;
1102     if (const PointerType* PT = retType->getAs<PointerType>())
1103       PointeeTy = PT->getPointeeType();
1104     else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>())
1105       PointeeTy = BPT->getPointeeType();
1106     if ((FPRetType = PointeeTy->getAs<FunctionType>())) {
1107       ResultStr += FPRetType->getResultType().getAsString(
1108         Context->getPrintingPolicy());
1109       ResultStr += "(*";
1110     }
1111   } else
1112     ResultStr += T.getAsString(Context->getPrintingPolicy());
1113 }
1114
1115 void RewriteModernObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
1116                                         ObjCMethodDecl *OMD,
1117                                         std::string &ResultStr) {
1118   //fprintf(stderr,"In RewriteObjCMethodDecl\n");
1119   const FunctionType *FPRetType = 0;
1120   ResultStr += "\nstatic ";
1121   RewriteTypeIntoString(OMD->getResultType(), ResultStr, FPRetType);
1122   ResultStr += " ";
1123
1124   // Unique method name
1125   std::string NameStr;
1126
1127   if (OMD->isInstanceMethod())
1128     NameStr += "_I_";
1129   else
1130     NameStr += "_C_";
1131
1132   NameStr += IDecl->getNameAsString();
1133   NameStr += "_";
1134
1135   if (ObjCCategoryImplDecl *CID =
1136       dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
1137     NameStr += CID->getNameAsString();
1138     NameStr += "_";
1139   }
1140   // Append selector names, replacing ':' with '_'
1141   {
1142     std::string selString = OMD->getSelector().getAsString();
1143     int len = selString.size();
1144     for (int i = 0; i < len; i++)
1145       if (selString[i] == ':')
1146         selString[i] = '_';
1147     NameStr += selString;
1148   }
1149   // Remember this name for metadata emission
1150   MethodInternalNames[OMD] = NameStr;
1151   ResultStr += NameStr;
1152
1153   // Rewrite arguments
1154   ResultStr += "(";
1155
1156   // invisible arguments
1157   if (OMD->isInstanceMethod()) {
1158     QualType selfTy = Context->getObjCInterfaceType(IDecl);
1159     selfTy = Context->getPointerType(selfTy);
1160     if (!LangOpts.MicrosoftExt) {
1161       if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
1162         ResultStr += "struct ";
1163     }
1164     // When rewriting for Microsoft, explicitly omit the structure name.
1165     ResultStr += IDecl->getNameAsString();
1166     ResultStr += " *";
1167   }
1168   else
1169     ResultStr += Context->getObjCClassType().getAsString(
1170       Context->getPrintingPolicy());
1171
1172   ResultStr += " self, ";
1173   ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
1174   ResultStr += " _cmd";
1175
1176   // Method arguments.
1177   for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
1178        E = OMD->param_end(); PI != E; ++PI) {
1179     ParmVarDecl *PDecl = *PI;
1180     ResultStr += ", ";
1181     if (PDecl->getType()->isObjCQualifiedIdType()) {
1182       ResultStr += "id ";
1183       ResultStr += PDecl->getNameAsString();
1184     } else {
1185       std::string Name = PDecl->getNameAsString();
1186       QualType QT = PDecl->getType();
1187       // Make sure we convert "t (^)(...)" to "t (*)(...)".
1188       (void)convertBlockPointerToFunctionPointer(QT);
1189       QT.getAsStringInternal(Name, Context->getPrintingPolicy());
1190       ResultStr += Name;
1191     }
1192   }
1193   if (OMD->isVariadic())
1194     ResultStr += ", ...";
1195   ResultStr += ") ";
1196
1197   if (FPRetType) {
1198     ResultStr += ")"; // close the precedence "scope" for "*".
1199
1200     // Now, emit the argument types (if any).
1201     if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
1202       ResultStr += "(";
1203       for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
1204         if (i) ResultStr += ", ";
1205         std::string ParamStr = FT->getArgType(i).getAsString(
1206           Context->getPrintingPolicy());
1207         ResultStr += ParamStr;
1208       }
1209       if (FT->isVariadic()) {
1210         if (FT->getNumArgs()) ResultStr += ", ";
1211         ResultStr += "...";
1212       }
1213       ResultStr += ")";
1214     } else {
1215       ResultStr += "()";
1216     }
1217   }
1218 }
1219 void RewriteModernObjC::RewriteImplementationDecl(Decl *OID) {
1220   ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
1221   ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
1222
1223   if (IMD) {
1224     InsertText(IMD->getLocStart(), "// ");
1225     if (IMD->getIvarLBraceLoc().isValid())
1226       InsertText(IMD->getIvarLBraceLoc(), "// ");
1227     for (ObjCImplementationDecl::ivar_iterator
1228          I = IMD->ivar_begin(), E = IMD->ivar_end(); I != E; ++I) {
1229       ObjCIvarDecl *Ivar = (*I);
1230       SourceLocation LocStart = Ivar->getLocStart();
1231       ReplaceText(LocStart, 0, "// ");
1232     }
1233     if (IMD->getIvarRBraceLoc().isValid())
1234       InsertText(IMD->getIvarRBraceLoc(), "// ");
1235   }
1236   else
1237     InsertText(CID->getLocStart(), "// ");
1238
1239   for (ObjCCategoryImplDecl::instmeth_iterator
1240        I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
1241        E = IMD ? IMD->instmeth_end() : CID->instmeth_end();
1242        I != E; ++I) {
1243     std::string ResultStr;
1244     ObjCMethodDecl *OMD = *I;
1245     RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
1246     SourceLocation LocStart = OMD->getLocStart();
1247     SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
1248
1249     const char *startBuf = SM->getCharacterData(LocStart);
1250     const char *endBuf = SM->getCharacterData(LocEnd);
1251     ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1252   }
1253
1254   for (ObjCCategoryImplDecl::classmeth_iterator
1255        I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(),
1256        E = IMD ? IMD->classmeth_end() : CID->classmeth_end();
1257        I != E; ++I) {
1258     std::string ResultStr;
1259     ObjCMethodDecl *OMD = *I;
1260     RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
1261     SourceLocation LocStart = OMD->getLocStart();
1262     SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
1263
1264     const char *startBuf = SM->getCharacterData(LocStart);
1265     const char *endBuf = SM->getCharacterData(LocEnd);
1266     ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1267   }
1268   for (ObjCCategoryImplDecl::propimpl_iterator
1269        I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
1270        E = IMD ? IMD->propimpl_end() : CID->propimpl_end();
1271        I != E; ++I) {
1272     RewritePropertyImplDecl(*I, IMD, CID);
1273   }
1274
1275   InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
1276 }
1277
1278 void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
1279   // Do not synthesize more than once.
1280   if (ObjCSynthesizedStructs.count(ClassDecl))
1281     return;
1282   // Make sure super class's are written before current class is written.
1283   ObjCInterfaceDecl *SuperClass = ClassDecl->getSuperClass();
1284   while (SuperClass) {
1285     RewriteInterfaceDecl(SuperClass);
1286     SuperClass = SuperClass->getSuperClass();
1287   }
1288   std::string ResultStr;
1289   if (!ObjCWrittenInterfaces.count(ClassDecl->getCanonicalDecl())) {
1290     // we haven't seen a forward decl - generate a typedef.
1291     RewriteOneForwardClassDecl(ClassDecl, ResultStr);
1292     RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1293     
1294     RewriteObjCInternalStruct(ClassDecl, ResultStr);
1295     // Mark this typedef as having been written into its c++ equivalent.
1296     ObjCWrittenInterfaces.insert(ClassDecl->getCanonicalDecl());
1297   
1298     for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(),
1299          E = ClassDecl->prop_end(); I != E; ++I)
1300       RewriteProperty(*I);
1301     for (ObjCInterfaceDecl::instmeth_iterator
1302          I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
1303          I != E; ++I)
1304       RewriteMethodDeclaration(*I);
1305     for (ObjCInterfaceDecl::classmeth_iterator
1306          I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
1307          I != E; ++I)
1308       RewriteMethodDeclaration(*I);
1309
1310     // Lastly, comment out the @end.
1311     ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
1312                 "/* @end */");
1313   }
1314 }
1315
1316 Stmt *RewriteModernObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
1317   SourceRange OldRange = PseudoOp->getSourceRange();
1318
1319   // We just magically know some things about the structure of this
1320   // expression.
1321   ObjCMessageExpr *OldMsg =
1322     cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr(
1323                             PseudoOp->getNumSemanticExprs() - 1));
1324
1325   // Because the rewriter doesn't allow us to rewrite rewritten code,
1326   // we need to suppress rewriting the sub-statements.
1327   Expr *Base;
1328   SmallVector<Expr*, 2> Args;
1329   {
1330     DisableReplaceStmtScope S(*this);
1331
1332     // Rebuild the base expression if we have one.
1333     Base = 0;
1334     if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
1335       Base = OldMsg->getInstanceReceiver();
1336       Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1337       Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1338     }
1339   
1340     unsigned numArgs = OldMsg->getNumArgs();
1341     for (unsigned i = 0; i < numArgs; i++) {
1342       Expr *Arg = OldMsg->getArg(i);
1343       if (isa<OpaqueValueExpr>(Arg))
1344         Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1345       Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1346       Args.push_back(Arg);
1347     }
1348   }
1349
1350   // TODO: avoid this copy.
1351   SmallVector<SourceLocation, 1> SelLocs;
1352   OldMsg->getSelectorLocs(SelLocs);
1353
1354   ObjCMessageExpr *NewMsg = 0;
1355   switch (OldMsg->getReceiverKind()) {
1356   case ObjCMessageExpr::Class:
1357     NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
1358                                      OldMsg->getValueKind(),
1359                                      OldMsg->getLeftLoc(),
1360                                      OldMsg->getClassReceiverTypeInfo(),
1361                                      OldMsg->getSelector(),
1362                                      SelLocs,
1363                                      OldMsg->getMethodDecl(),
1364                                      Args,
1365                                      OldMsg->getRightLoc(),
1366                                      OldMsg->isImplicit());
1367     break;
1368
1369   case ObjCMessageExpr::Instance:
1370     NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
1371                                      OldMsg->getValueKind(),
1372                                      OldMsg->getLeftLoc(),
1373                                      Base,
1374                                      OldMsg->getSelector(),
1375                                      SelLocs,
1376                                      OldMsg->getMethodDecl(),
1377                                      Args,
1378                                      OldMsg->getRightLoc(),
1379                                      OldMsg->isImplicit());
1380     break;
1381
1382   case ObjCMessageExpr::SuperClass:
1383   case ObjCMessageExpr::SuperInstance:
1384     NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
1385                                      OldMsg->getValueKind(),
1386                                      OldMsg->getLeftLoc(),
1387                                      OldMsg->getSuperLoc(),
1388                  OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
1389                                      OldMsg->getSuperType(),
1390                                      OldMsg->getSelector(),
1391                                      SelLocs,
1392                                      OldMsg->getMethodDecl(),
1393                                      Args,
1394                                      OldMsg->getRightLoc(),
1395                                      OldMsg->isImplicit());
1396     break;
1397   }
1398
1399   Stmt *Replacement = SynthMessageExpr(NewMsg);
1400   ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1401   return Replacement;
1402 }
1403
1404 Stmt *RewriteModernObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) {
1405   SourceRange OldRange = PseudoOp->getSourceRange();
1406
1407   // We just magically know some things about the structure of this
1408   // expression.
1409   ObjCMessageExpr *OldMsg =
1410     cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit());
1411
1412   // Because the rewriter doesn't allow us to rewrite rewritten code,
1413   // we need to suppress rewriting the sub-statements.
1414   Expr *Base = 0;
1415   SmallVector<Expr*, 1> Args;
1416   {
1417     DisableReplaceStmtScope S(*this);
1418     // Rebuild the base expression if we have one.
1419     if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
1420       Base = OldMsg->getInstanceReceiver();
1421       Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1422       Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1423     }
1424     unsigned numArgs = OldMsg->getNumArgs();
1425     for (unsigned i = 0; i < numArgs; i++) {
1426       Expr *Arg = OldMsg->getArg(i);
1427       if (isa<OpaqueValueExpr>(Arg))
1428         Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1429       Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1430       Args.push_back(Arg);
1431     }
1432   }
1433
1434   // Intentionally empty.
1435   SmallVector<SourceLocation, 1> SelLocs;
1436
1437   ObjCMessageExpr *NewMsg = 0;
1438   switch (OldMsg->getReceiverKind()) {
1439   case ObjCMessageExpr::Class:
1440     NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
1441                                      OldMsg->getValueKind(),
1442                                      OldMsg->getLeftLoc(),
1443                                      OldMsg->getClassReceiverTypeInfo(),
1444                                      OldMsg->getSelector(),
1445                                      SelLocs,
1446                                      OldMsg->getMethodDecl(),
1447                                      Args,
1448                                      OldMsg->getRightLoc(),
1449                                      OldMsg->isImplicit());
1450     break;
1451
1452   case ObjCMessageExpr::Instance:
1453     NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
1454                                      OldMsg->getValueKind(),
1455                                      OldMsg->getLeftLoc(),
1456                                      Base,
1457                                      OldMsg->getSelector(),
1458                                      SelLocs,
1459                                      OldMsg->getMethodDecl(),
1460                                      Args,
1461                                      OldMsg->getRightLoc(),
1462                                      OldMsg->isImplicit());
1463     break;
1464
1465   case ObjCMessageExpr::SuperClass:
1466   case ObjCMessageExpr::SuperInstance:
1467     NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
1468                                      OldMsg->getValueKind(),
1469                                      OldMsg->getLeftLoc(),
1470                                      OldMsg->getSuperLoc(),
1471                  OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
1472                                      OldMsg->getSuperType(),
1473                                      OldMsg->getSelector(),
1474                                      SelLocs,
1475                                      OldMsg->getMethodDecl(),
1476                                      Args,
1477                                      OldMsg->getRightLoc(),
1478                                      OldMsg->isImplicit());
1479     break;
1480   }
1481
1482   Stmt *Replacement = SynthMessageExpr(NewMsg);
1483   ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1484   return Replacement;
1485 }
1486
1487 /// SynthCountByEnumWithState - To print:
1488 /// ((unsigned int (*)
1489 ///  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
1490 ///  (void *)objc_msgSend)((id)l_collection,
1491 ///                        sel_registerName(
1492 ///                          "countByEnumeratingWithState:objects:count:"),
1493 ///                        &enumState,
1494 ///                        (id *)__rw_items, (unsigned int)16)
1495 ///
1496 void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
1497   buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, "
1498   "id *, unsigned int))(void *)objc_msgSend)";
1499   buf += "\n\t\t";
1500   buf += "((id)l_collection,\n\t\t";
1501   buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1502   buf += "\n\t\t";
1503   buf += "&enumState, "
1504          "(id *)__rw_items, (unsigned int)16)";
1505 }
1506
1507 /// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
1508 /// statement to exit to its outer synthesized loop.
1509 ///
1510 Stmt *RewriteModernObjC::RewriteBreakStmt(BreakStmt *S) {
1511   if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1512     return S;
1513   // replace break with goto __break_label
1514   std::string buf;
1515
1516   SourceLocation startLoc = S->getLocStart();
1517   buf = "goto __break_label_";
1518   buf += utostr(ObjCBcLabelNo.back());
1519   ReplaceText(startLoc, strlen("break"), buf);
1520
1521   return 0;
1522 }
1523
1524 /// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
1525 /// statement to continue with its inner synthesized loop.
1526 ///
1527 Stmt *RewriteModernObjC::RewriteContinueStmt(ContinueStmt *S) {
1528   if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1529     return S;
1530   // replace continue with goto __continue_label
1531   std::string buf;
1532
1533   SourceLocation startLoc = S->getLocStart();
1534   buf = "goto __continue_label_";
1535   buf += utostr(ObjCBcLabelNo.back());
1536   ReplaceText(startLoc, strlen("continue"), buf);
1537
1538   return 0;
1539 }
1540
1541 /// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
1542 ///  It rewrites:
1543 /// for ( type elem in collection) { stmts; }
1544
1545 /// Into:
1546 /// {
1547 ///   type elem;
1548 ///   struct __objcFastEnumerationState enumState = { 0 };
1549 ///   id __rw_items[16];
1550 ///   id l_collection = (id)collection;
1551 ///   unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
1552 ///                                       objects:__rw_items count:16];
1553 /// if (limit) {
1554 ///   unsigned long startMutations = *enumState.mutationsPtr;
1555 ///   do {
1556 ///        unsigned long counter = 0;
1557 ///        do {
1558 ///             if (startMutations != *enumState.mutationsPtr)
1559 ///               objc_enumerationMutation(l_collection);
1560 ///             elem = (type)enumState.itemsPtr[counter++];
1561 ///             stmts;
1562 ///             __continue_label: ;
1563 ///        } while (counter < limit);
1564 ///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
1565 ///                                  objects:__rw_items count:16]);
1566 ///   elem = nil;
1567 ///   __break_label: ;
1568 ///  }
1569 ///  else
1570 ///       elem = nil;
1571 ///  }
1572 ///
1573 Stmt *RewriteModernObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
1574                                                 SourceLocation OrigEnd) {
1575   assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty");
1576   assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1577          "ObjCForCollectionStmt Statement stack mismatch");
1578   assert(!ObjCBcLabelNo.empty() &&
1579          "ObjCForCollectionStmt - Label No stack empty");
1580
1581   SourceLocation startLoc = S->getLocStart();
1582   const char *startBuf = SM->getCharacterData(startLoc);
1583   StringRef elementName;
1584   std::string elementTypeAsString;
1585   std::string buf;
1586   buf = "\n{\n\t";
1587   if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
1588     // type elem;
1589     NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
1590     QualType ElementType = cast<ValueDecl>(D)->getType();
1591     if (ElementType->isObjCQualifiedIdType() ||
1592         ElementType->isObjCQualifiedInterfaceType())
1593       // Simply use 'id' for all qualified types.
1594       elementTypeAsString = "id";
1595     else
1596       elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy());
1597     buf += elementTypeAsString;
1598     buf += " ";
1599     elementName = D->getName();
1600     buf += elementName;
1601     buf += ";\n\t";
1602   }
1603   else {
1604     DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
1605     elementName = DR->getDecl()->getName();
1606     ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
1607     if (VD->getType()->isObjCQualifiedIdType() ||
1608         VD->getType()->isObjCQualifiedInterfaceType())
1609       // Simply use 'id' for all qualified types.
1610       elementTypeAsString = "id";
1611     else
1612       elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy());
1613   }
1614
1615   // struct __objcFastEnumerationState enumState = { 0 };
1616   buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
1617   // id __rw_items[16];
1618   buf += "id __rw_items[16];\n\t";
1619   // id l_collection = (id)
1620   buf += "id l_collection = (id)";
1621   // Find start location of 'collection' the hard way!
1622   const char *startCollectionBuf = startBuf;
1623   startCollectionBuf += 3;  // skip 'for'
1624   startCollectionBuf = strchr(startCollectionBuf, '(');
1625   startCollectionBuf++; // skip '('
1626   // find 'in' and skip it.
1627   while (*startCollectionBuf != ' ' ||
1628          *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' ||
1629          (*(startCollectionBuf+3) != ' ' &&
1630           *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '('))
1631     startCollectionBuf++;
1632   startCollectionBuf += 3;
1633
1634   // Replace: "for (type element in" with string constructed thus far.
1635   ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1636   // Replace ')' in for '(' type elem in collection ')' with ';'
1637   SourceLocation rightParenLoc = S->getRParenLoc();
1638   const char *rparenBuf = SM->getCharacterData(rightParenLoc);
1639   SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf);
1640   buf = ";\n\t";
1641
1642   // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
1643   //                                   objects:__rw_items count:16];
1644   // which is synthesized into:
1645   // unsigned int limit =
1646   // ((unsigned int (*)
1647   //  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
1648   //  (void *)objc_msgSend)((id)l_collection,
1649   //                        sel_registerName(
1650   //                          "countByEnumeratingWithState:objects:count:"),
1651   //                        (struct __objcFastEnumerationState *)&state,
1652   //                        (id *)__rw_items, (unsigned int)16);
1653   buf += "unsigned long limit =\n\t\t";
1654   SynthCountByEnumWithState(buf);
1655   buf += ";\n\t";
1656   /// if (limit) {
1657   ///   unsigned long startMutations = *enumState.mutationsPtr;
1658   ///   do {
1659   ///        unsigned long counter = 0;
1660   ///        do {
1661   ///             if (startMutations != *enumState.mutationsPtr)
1662   ///               objc_enumerationMutation(l_collection);
1663   ///             elem = (type)enumState.itemsPtr[counter++];
1664   buf += "if (limit) {\n\t";
1665   buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1666   buf += "do {\n\t\t";
1667   buf += "unsigned long counter = 0;\n\t\t";
1668   buf += "do {\n\t\t\t";
1669   buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1670   buf += "objc_enumerationMutation(l_collection);\n\t\t\t";
1671   buf += elementName;
1672   buf += " = (";
1673   buf += elementTypeAsString;
1674   buf += ")enumState.itemsPtr[counter++];";
1675   // Replace ')' in for '(' type elem in collection ')' with all of these.
1676   ReplaceText(lparenLoc, 1, buf);
1677
1678   ///            __continue_label: ;
1679   ///        } while (counter < limit);
1680   ///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
1681   ///                                  objects:__rw_items count:16]);
1682   ///   elem = nil;
1683   ///   __break_label: ;
1684   ///  }
1685   ///  else
1686   ///       elem = nil;
1687   ///  }
1688   ///
1689   buf = ";\n\t";
1690   buf += "__continue_label_";
1691   buf += utostr(ObjCBcLabelNo.back());
1692   buf += ": ;";
1693   buf += "\n\t\t";
1694   buf += "} while (counter < limit);\n\t";
1695   buf += "} while (limit = ";
1696   SynthCountByEnumWithState(buf);
1697   buf += ");\n\t";
1698   buf += elementName;
1699   buf += " = ((";
1700   buf += elementTypeAsString;
1701   buf += ")0);\n\t";
1702   buf += "__break_label_";
1703   buf += utostr(ObjCBcLabelNo.back());
1704   buf += ": ;\n\t";
1705   buf += "}\n\t";
1706   buf += "else\n\t\t";
1707   buf += elementName;
1708   buf += " = ((";
1709   buf += elementTypeAsString;
1710   buf += ")0);\n\t";
1711   buf += "}\n";
1712
1713   // Insert all these *after* the statement body.
1714   // FIXME: If this should support Obj-C++, support CXXTryStmt
1715   if (isa<CompoundStmt>(S->getBody())) {
1716     SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1);
1717     InsertText(endBodyLoc, buf);
1718   } else {
1719     /* Need to treat single statements specially. For example:
1720      *
1721      *     for (A *a in b) if (stuff()) break;
1722      *     for (A *a in b) xxxyy;
1723      *
1724      * The following code simply scans ahead to the semi to find the actual end.
1725      */
1726     const char *stmtBuf = SM->getCharacterData(OrigEnd);
1727     const char *semiBuf = strchr(stmtBuf, ';');
1728     assert(semiBuf && "Can't find ';'");
1729     SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1);
1730     InsertText(endBodyLoc, buf);
1731   }
1732   Stmts.pop_back();
1733   ObjCBcLabelNo.pop_back();
1734   return 0;
1735 }
1736
1737 static void Write_RethrowObject(std::string &buf) {
1738   buf += "{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1739   buf += "\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1740   buf += "\tid rethrow;\n";
1741   buf += "\t} _fin_force_rethow(_rethrow);";
1742 }
1743
1744 /// RewriteObjCSynchronizedStmt -
1745 /// This routine rewrites @synchronized(expr) stmt;
1746 /// into:
1747 /// objc_sync_enter(expr);
1748 /// @try stmt @finally { objc_sync_exit(expr); }
1749 ///
1750 Stmt *RewriteModernObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
1751   // Get the start location and compute the semi location.
1752   SourceLocation startLoc = S->getLocStart();
1753   const char *startBuf = SM->getCharacterData(startLoc);
1754
1755   assert((*startBuf == '@') && "bogus @synchronized location");
1756
1757   std::string buf;
1758   buf = "{ id _rethrow = 0; id _sync_obj = ";
1759   
1760   const char *lparenBuf = startBuf;
1761   while (*lparenBuf != '(') lparenBuf++;
1762   ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1763   
1764   buf = "; objc_sync_enter(_sync_obj);\n";
1765   buf += "try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1766   buf += "\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1767   buf += "\n\tid sync_exit;";
1768   buf += "\n\t} _sync_exit(_sync_obj);\n";
1769
1770   // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
1771   // the sync expression is typically a message expression that's already
1772   // been rewritten! (which implies the SourceLocation's are invalid).
1773   SourceLocation RParenExprLoc = S->getSynchBody()->getLocStart();
1774   const char *RParenExprLocBuf = SM->getCharacterData(RParenExprLoc);
1775   while (*RParenExprLocBuf != ')') RParenExprLocBuf--;
1776   RParenExprLoc = startLoc.getLocWithOffset(RParenExprLocBuf-startBuf);
1777   
1778   SourceLocation LBranceLoc = S->getSynchBody()->getLocStart();
1779   const char *LBraceLocBuf = SM->getCharacterData(LBranceLoc);
1780   assert (*LBraceLocBuf == '{');
1781   ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->getCharacterData(RParenExprLoc) + 1), buf);
1782   
1783   SourceLocation startRBraceLoc = S->getSynchBody()->getLocEnd();
1784   assert((*SM->getCharacterData(startRBraceLoc) == '}') &&
1785          "bogus @synchronized block");
1786   
1787   buf = "} catch (id e) {_rethrow = e;}\n";
1788   Write_RethrowObject(buf);
1789   buf += "}\n";
1790   buf += "}\n";
1791
1792   ReplaceText(startRBraceLoc, 1, buf);
1793
1794   return 0;
1795 }
1796
1797 void RewriteModernObjC::WarnAboutReturnGotoStmts(Stmt *S)
1798 {
1799   // Perform a bottom up traversal of all children.
1800   for (Stmt::child_range CI = S->children(); CI; ++CI)
1801     if (*CI)
1802       WarnAboutReturnGotoStmts(*CI);
1803
1804   if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1805     Diags.Report(Context->getFullLoc(S->getLocStart()),
1806                  TryFinallyContainsReturnDiag);
1807   }
1808   return;
1809 }
1810
1811 Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
1812   ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt();
1813   bool noCatch = S->getNumCatchStmts() == 0;
1814   std::string buf;
1815   
1816   if (finalStmt) {
1817     if (noCatch)
1818       buf = "{ id volatile _rethrow = 0;\n";
1819     else {
1820       buf = "{ id volatile _rethrow = 0;\ntry {\n";
1821     }
1822   }
1823   // Get the start location and compute the semi location.
1824   SourceLocation startLoc = S->getLocStart();
1825   const char *startBuf = SM->getCharacterData(startLoc);
1826
1827   assert((*startBuf == '@') && "bogus @try location");
1828   if (finalStmt)
1829     ReplaceText(startLoc, 1, buf);
1830   else
1831     // @try -> try
1832     ReplaceText(startLoc, 1, "");
1833   
1834   for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
1835     ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
1836     VarDecl *catchDecl = Catch->getCatchParamDecl();
1837     
1838     startLoc = Catch->getLocStart();
1839     bool AtRemoved = false;
1840     if (catchDecl) {
1841       QualType t = catchDecl->getType();
1842       if (const ObjCObjectPointerType *Ptr = t->getAs<ObjCObjectPointerType>()) {
1843         // Should be a pointer to a class.
1844         ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
1845         if (IDecl) {
1846           std::string Result;
1847           startBuf = SM->getCharacterData(startLoc);
1848           assert((*startBuf == '@') && "bogus @catch location");
1849           SourceLocation rParenLoc = Catch->getRParenLoc();
1850           const char *rParenBuf = SM->getCharacterData(rParenLoc);
1851           
1852           // _objc_exc_Foo *_e as argument to catch.
1853           Result = "catch (_objc_exc_"; Result += IDecl->getNameAsString();
1854           Result += " *_"; Result += catchDecl->getNameAsString();
1855           Result += ")";
1856           ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
1857           // Foo *e = (Foo *)_e;
1858           Result.clear();
1859           Result = "{ ";
1860           Result += IDecl->getNameAsString();
1861           Result += " *"; Result += catchDecl->getNameAsString();
1862           Result += " = ("; Result += IDecl->getNameAsString(); Result += "*)";
1863           Result += "_"; Result += catchDecl->getNameAsString();
1864           
1865           Result += "; ";
1866           SourceLocation lBraceLoc = Catch->getCatchBody()->getLocStart();
1867           ReplaceText(lBraceLoc, 1, Result);
1868           AtRemoved = true;
1869         }
1870       }
1871     }
1872     if (!AtRemoved)
1873       // @catch -> catch
1874       ReplaceText(startLoc, 1, "");
1875       
1876   }
1877   if (finalStmt) {
1878     buf.clear();
1879     if (noCatch)
1880       buf = "catch (id e) {_rethrow = e;}\n";
1881     else 
1882       buf = "}\ncatch (id e) {_rethrow = e;}\n";
1883
1884     SourceLocation startFinalLoc = finalStmt->getLocStart();
1885     ReplaceText(startFinalLoc, 8, buf);
1886     Stmt *body = finalStmt->getFinallyBody();
1887     SourceLocation startFinalBodyLoc = body->getLocStart();
1888     buf.clear();
1889     Write_RethrowObject(buf);
1890     ReplaceText(startFinalBodyLoc, 1, buf);
1891     
1892     SourceLocation endFinalBodyLoc = body->getLocEnd();
1893     ReplaceText(endFinalBodyLoc, 1, "}\n}");
1894     // Now check for any return/continue/go statements within the @try.
1895     WarnAboutReturnGotoStmts(S->getTryBody());
1896   }
1897
1898   return 0;
1899 }
1900
1901 // This can't be done with ReplaceStmt(S, ThrowExpr), since
1902 // the throw expression is typically a message expression that's already
1903 // been rewritten! (which implies the SourceLocation's are invalid).
1904 Stmt *RewriteModernObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
1905   // Get the start location and compute the semi location.
1906   SourceLocation startLoc = S->getLocStart();
1907   const char *startBuf = SM->getCharacterData(startLoc);
1908
1909   assert((*startBuf == '@') && "bogus @throw location");
1910
1911   std::string buf;
1912   /* void objc_exception_throw(id) __attribute__((noreturn)); */
1913   if (S->getThrowExpr())
1914     buf = "objc_exception_throw(";
1915   else
1916     buf = "throw";
1917
1918   // handle "@  throw" correctly.
1919   const char *wBuf = strchr(startBuf, 'w');
1920   assert((*wBuf == 'w') && "@throw: can't find 'w'");
1921   ReplaceText(startLoc, wBuf-startBuf+1, buf);
1922
1923   const char *semiBuf = strchr(startBuf, ';');
1924   assert((*semiBuf == ';') && "@throw: can't find ';'");
1925   SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf);
1926   if (S->getThrowExpr())
1927     ReplaceText(semiLoc, 1, ");");
1928   return 0;
1929 }
1930
1931 Stmt *RewriteModernObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
1932   // Create a new string expression.
1933   QualType StrType = Context->getPointerType(Context->CharTy);
1934   std::string StrEncoding;
1935   Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
1936   Expr *Replacement = StringLiteral::Create(*Context, StrEncoding,
1937                                             StringLiteral::Ascii, false,
1938                                             StrType, SourceLocation());
1939   ReplaceStmt(Exp, Replacement);
1940
1941   // Replace this subexpr in the parent.
1942   // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
1943   return Replacement;
1944 }
1945
1946 Stmt *RewriteModernObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
1947   if (!SelGetUidFunctionDecl)
1948     SynthSelGetUidFunctionDecl();
1949   assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
1950   // Create a call to sel_registerName("selName").
1951   SmallVector<Expr*, 8> SelExprs;
1952   QualType argType = Context->getPointerType(Context->CharTy);
1953   SelExprs.push_back(StringLiteral::Create(*Context,
1954                                            Exp->getSelector().getAsString(),
1955                                            StringLiteral::Ascii, false,
1956                                            argType, SourceLocation()));
1957   CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
1958                                                  &SelExprs[0], SelExprs.size());
1959   ReplaceStmt(Exp, SelExp);
1960   // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
1961   return SelExp;
1962 }
1963
1964 CallExpr *RewriteModernObjC::SynthesizeCallToFunctionDecl(
1965   FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
1966                                                     SourceLocation EndLoc) {
1967   // Get the type, we will need to reference it in a couple spots.
1968   QualType msgSendType = FD->getType();
1969
1970   // Create a reference to the objc_msgSend() declaration.
1971   DeclRefExpr *DRE =
1972     new (Context) DeclRefExpr(FD, false, msgSendType, VK_LValue, SourceLocation());
1973
1974   // Now, we cast the reference to a pointer to the objc_msgSend type.
1975   QualType pToFunc = Context->getPointerType(msgSendType);
1976   ImplicitCastExpr *ICE = 
1977     ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
1978                              DRE, 0, VK_RValue);
1979
1980   const FunctionType *FT = msgSendType->getAs<FunctionType>();
1981
1982   CallExpr *Exp =  
1983     new (Context) CallExpr(*Context, ICE, args, nargs, 
1984                            FT->getCallResultType(*Context),
1985                            VK_RValue, EndLoc);
1986   return Exp;
1987 }
1988
1989 static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
1990                                 const char *&startRef, const char *&endRef) {
1991   while (startBuf < endBuf) {
1992     if (*startBuf == '<')
1993       startRef = startBuf; // mark the start.
1994     if (*startBuf == '>') {
1995       if (startRef && *startRef == '<') {
1996         endRef = startBuf; // mark the end.
1997         return true;
1998       }
1999       return false;
2000     }
2001     startBuf++;
2002   }
2003   return false;
2004 }
2005
2006 static void scanToNextArgument(const char *&argRef) {
2007   int angle = 0;
2008   while (*argRef != ')' && (*argRef != ',' || angle > 0)) {
2009     if (*argRef == '<')
2010       angle++;
2011     else if (*argRef == '>')
2012       angle--;
2013     argRef++;
2014   }
2015   assert(angle == 0 && "scanToNextArgument - bad protocol type syntax");
2016 }
2017
2018 bool RewriteModernObjC::needToScanForQualifiers(QualType T) {
2019   if (T->isObjCQualifiedIdType())
2020     return true;
2021   if (const PointerType *PT = T->getAs<PointerType>()) {
2022     if (PT->getPointeeType()->isObjCQualifiedIdType())
2023       return true;
2024   }
2025   if (T->isObjCObjectPointerType()) {
2026     T = T->getPointeeType();
2027     return T->isObjCQualifiedInterfaceType();
2028   }
2029   if (T->isArrayType()) {
2030     QualType ElemTy = Context->getBaseElementType(T);
2031     return needToScanForQualifiers(ElemTy);
2032   }
2033   return false;
2034 }
2035
2036 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
2037   QualType Type = E->getType();
2038   if (needToScanForQualifiers(Type)) {
2039     SourceLocation Loc, EndLoc;
2040
2041     if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) {
2042       Loc = ECE->getLParenLoc();
2043       EndLoc = ECE->getRParenLoc();
2044     } else {
2045       Loc = E->getLocStart();
2046       EndLoc = E->getLocEnd();
2047     }
2048     // This will defend against trying to rewrite synthesized expressions.
2049     if (Loc.isInvalid() || EndLoc.isInvalid())
2050       return;
2051
2052     const char *startBuf = SM->getCharacterData(Loc);
2053     const char *endBuf = SM->getCharacterData(EndLoc);
2054     const char *startRef = 0, *endRef = 0;
2055     if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2056       // Get the locations of the startRef, endRef.
2057       SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf);
2058       SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1);
2059       // Comment out the protocol references.
2060       InsertText(LessLoc, "/*");
2061       InsertText(GreaterLoc, "*/");
2062     }
2063   }
2064 }
2065
2066 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
2067   SourceLocation Loc;
2068   QualType Type;
2069   const FunctionProtoType *proto = 0;
2070   if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2071     Loc = VD->getLocation();
2072     Type = VD->getType();
2073   }
2074   else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2075     Loc = FD->getLocation();
2076     // Check for ObjC 'id' and class types that have been adorned with protocol
2077     // information (id<p>, C<p>*). The protocol references need to be rewritten!
2078     const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
2079     assert(funcType && "missing function type");
2080     proto = dyn_cast<FunctionProtoType>(funcType);
2081     if (!proto)
2082       return;
2083     Type = proto->getResultType();
2084   }
2085   else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2086     Loc = FD->getLocation();
2087     Type = FD->getType();
2088   }
2089   else
2090     return;
2091
2092   if (needToScanForQualifiers(Type)) {
2093     // Since types are unique, we need to scan the buffer.
2094
2095     const char *endBuf = SM->getCharacterData(Loc);
2096     const char *startBuf = endBuf;
2097     while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart)
2098       startBuf--; // scan backward (from the decl location) for return type.
2099     const char *startRef = 0, *endRef = 0;
2100     if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2101       // Get the locations of the startRef, endRef.
2102       SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf);
2103       SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1);
2104       // Comment out the protocol references.
2105       InsertText(LessLoc, "/*");
2106       InsertText(GreaterLoc, "*/");
2107     }
2108   }
2109   if (!proto)
2110       return; // most likely, was a variable
2111   // Now check arguments.
2112   const char *startBuf = SM->getCharacterData(Loc);
2113   const char *startFuncBuf = startBuf;
2114   for (unsigned i = 0; i < proto->getNumArgs(); i++) {
2115     if (needToScanForQualifiers(proto->getArgType(i))) {
2116       // Since types are unique, we need to scan the buffer.
2117
2118       const char *endBuf = startBuf;
2119       // scan forward (from the decl location) for argument types.
2120       scanToNextArgument(endBuf);
2121       const char *startRef = 0, *endRef = 0;
2122       if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2123         // Get the locations of the startRef, endRef.
2124         SourceLocation LessLoc =
2125           Loc.getLocWithOffset(startRef-startFuncBuf);
2126         SourceLocation GreaterLoc =
2127           Loc.getLocWithOffset(endRef-startFuncBuf+1);
2128         // Comment out the protocol references.
2129         InsertText(LessLoc, "/*");
2130         InsertText(GreaterLoc, "*/");
2131       }
2132       startBuf = ++endBuf;
2133     }
2134     else {
2135       // If the function name is derived from a macro expansion, then the
2136       // argument buffer will not follow the name. Need to speak with Chris.
2137       while (*startBuf && *startBuf != ')' && *startBuf != ',')
2138         startBuf++; // scan forward (from the decl location) for argument types.
2139       startBuf++;
2140     }
2141   }
2142 }
2143
2144 void RewriteModernObjC::RewriteTypeOfDecl(VarDecl *ND) {
2145   QualType QT = ND->getType();
2146   const Type* TypePtr = QT->getAs<Type>();
2147   if (!isa<TypeOfExprType>(TypePtr))
2148     return;
2149   while (isa<TypeOfExprType>(TypePtr)) {
2150     const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2151     QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
2152     TypePtr = QT->getAs<Type>();
2153   }
2154   // FIXME. This will not work for multiple declarators; as in:
2155   // __typeof__(a) b,c,d;
2156   std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy()));
2157   SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
2158   const char *startBuf = SM->getCharacterData(DeclLoc);
2159   if (ND->getInit()) {
2160     std::string Name(ND->getNameAsString());
2161     TypeAsString += " " + Name + " = ";
2162     Expr *E = ND->getInit();
2163     SourceLocation startLoc;
2164     if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
2165       startLoc = ECE->getLParenLoc();
2166     else
2167       startLoc = E->getLocStart();
2168     startLoc = SM->getExpansionLoc(startLoc);
2169     const char *endBuf = SM->getCharacterData(startLoc);
2170     ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2171   }
2172   else {
2173     SourceLocation X = ND->getLocEnd();
2174     X = SM->getExpansionLoc(X);
2175     const char *endBuf = SM->getCharacterData(X);
2176     ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2177   }
2178 }
2179
2180 // SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
2181 void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2182   IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
2183   SmallVector<QualType, 16> ArgTys;
2184   ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2185   QualType getFuncType =
2186     getSimpleFunctionType(Context->getObjCSelType(), &ArgTys[0], ArgTys.size());
2187   SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2188                                            SourceLocation(),
2189                                            SourceLocation(),
2190                                            SelGetUidIdent, getFuncType, 0,
2191                                            SC_Extern,
2192                                            SC_None, false);
2193 }
2194
2195 void RewriteModernObjC::RewriteFunctionDecl(FunctionDecl *FD) {
2196   // declared in <objc/objc.h>
2197   if (FD->getIdentifier() &&
2198       FD->getName() == "sel_registerName") {
2199     SelGetUidFunctionDecl = FD;
2200     return;
2201   }
2202   RewriteObjCQualifiedInterfaceTypes(FD);
2203 }
2204
2205 void RewriteModernObjC::RewriteBlockPointerType(std::string& Str, QualType Type) {
2206   std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
2207   const char *argPtr = TypeString.c_str();
2208   if (!strchr(argPtr, '^')) {
2209     Str += TypeString;
2210     return;
2211   }
2212   while (*argPtr) {
2213     Str += (*argPtr == '^' ? '*' : *argPtr);
2214     argPtr++;
2215   }
2216 }
2217
2218 // FIXME. Consolidate this routine with RewriteBlockPointerType.
2219 void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2220                                                   ValueDecl *VD) {
2221   QualType Type = VD->getType();
2222   std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
2223   const char *argPtr = TypeString.c_str();
2224   int paren = 0;
2225   while (*argPtr) {
2226     switch (*argPtr) {
2227       case '(':
2228         Str += *argPtr;
2229         paren++;
2230         break;
2231       case ')':
2232         Str += *argPtr;
2233         paren--;
2234         break;
2235       case '^':
2236         Str += '*';
2237         if (paren == 1)
2238           Str += VD->getNameAsString();
2239         break;
2240       default:
2241         Str += *argPtr;
2242         break;
2243     }
2244     argPtr++;
2245   }
2246 }
2247
2248 // SynthSuperContructorFunctionDecl - id __rw_objc_super(id obj, id super);
2249 void RewriteModernObjC::SynthSuperContructorFunctionDecl() {
2250   if (SuperContructorFunctionDecl)
2251     return;
2252   IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super");
2253   SmallVector<QualType, 16> ArgTys;
2254   QualType argT = Context->getObjCIdType();
2255   assert(!argT.isNull() && "Can't find 'id' type");
2256   ArgTys.push_back(argT);
2257   ArgTys.push_back(argT);
2258   QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2259                                                &ArgTys[0], ArgTys.size());
2260   SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2261                                          SourceLocation(),
2262                                          SourceLocation(),
2263                                          msgSendIdent, msgSendType, 0,
2264                                          SC_Extern,
2265                                          SC_None, false);
2266 }
2267
2268 // SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
2269 void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2270   IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
2271   SmallVector<QualType, 16> ArgTys;
2272   QualType argT = Context->getObjCIdType();
2273   assert(!argT.isNull() && "Can't find 'id' type");
2274   ArgTys.push_back(argT);
2275   argT = Context->getObjCSelType();
2276   assert(!argT.isNull() && "Can't find 'SEL' type");
2277   ArgTys.push_back(argT);
2278   QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2279                                                &ArgTys[0], ArgTys.size(),
2280                                                true /*isVariadic*/);
2281   MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2282                                          SourceLocation(),
2283                                          SourceLocation(),
2284                                          msgSendIdent, msgSendType, 0,
2285                                          SC_Extern,
2286                                          SC_None, false);
2287 }
2288
2289 // SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(void);
2290 void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2291   IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
2292   SmallVector<QualType, 2> ArgTys;
2293   ArgTys.push_back(Context->VoidTy);
2294   QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2295                                                &ArgTys[0], 1,
2296                                                true /*isVariadic*/);
2297   MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2298                                               SourceLocation(),
2299                                               SourceLocation(),
2300                                               msgSendIdent, msgSendType, 0,
2301                                               SC_Extern,
2302                                               SC_None, false);
2303 }
2304
2305 // SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
2306 void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2307   IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
2308   SmallVector<QualType, 16> ArgTys;
2309   QualType argT = Context->getObjCIdType();
2310   assert(!argT.isNull() && "Can't find 'id' type");
2311   ArgTys.push_back(argT);
2312   argT = Context->getObjCSelType();
2313   assert(!argT.isNull() && "Can't find 'SEL' type");
2314   ArgTys.push_back(argT);
2315   QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2316                                                &ArgTys[0], ArgTys.size(),
2317                                                true /*isVariadic*/);
2318   MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2319                                          SourceLocation(),
2320                                          SourceLocation(),
2321                                          msgSendIdent, msgSendType, 0,
2322                                          SC_Extern,
2323                                          SC_None, false);
2324 }
2325
2326 // SynthMsgSendSuperStretFunctionDecl -
2327 // id objc_msgSendSuper_stret(void);
2328 void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2329   IdentifierInfo *msgSendIdent =
2330     &Context->Idents.get("objc_msgSendSuper_stret");
2331   SmallVector<QualType, 2> ArgTys;
2332   ArgTys.push_back(Context->VoidTy);
2333   QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2334                                                &ArgTys[0], 1,
2335                                                true /*isVariadic*/);
2336   MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2337                                                        SourceLocation(),
2338                                                        SourceLocation(),
2339                                               msgSendIdent, msgSendType, 0,
2340                                               SC_Extern,
2341                                               SC_None, false);
2342 }
2343
2344 // SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
2345 void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2346   IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
2347   SmallVector<QualType, 16> ArgTys;
2348   QualType argT = Context->getObjCIdType();
2349   assert(!argT.isNull() && "Can't find 'id' type");
2350   ArgTys.push_back(argT);
2351   argT = Context->getObjCSelType();
2352   assert(!argT.isNull() && "Can't find 'SEL' type");
2353   ArgTys.push_back(argT);
2354   QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
2355                                                &ArgTys[0], ArgTys.size(),
2356                                                true /*isVariadic*/);
2357   MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2358                                               SourceLocation(),
2359                                               SourceLocation(),
2360                                               msgSendIdent, msgSendType, 0,
2361                                               SC_Extern,
2362                                               SC_None, false);
2363 }
2364
2365 // SynthGetClassFunctionDecl - id objc_getClass(const char *name);
2366 void RewriteModernObjC::SynthGetClassFunctionDecl() {
2367   IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
2368   SmallVector<QualType, 16> ArgTys;
2369   ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2370   QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(),
2371                                                 &ArgTys[0], ArgTys.size());
2372   GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2373                                           SourceLocation(),
2374                                           SourceLocation(),
2375                                           getClassIdent, getClassType, 0,
2376                                           SC_Extern,
2377                                           SC_None, false);
2378 }
2379
2380 // SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
2381 void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2382   IdentifierInfo *getSuperClassIdent = 
2383     &Context->Idents.get("class_getSuperclass");
2384   SmallVector<QualType, 16> ArgTys;
2385   ArgTys.push_back(Context->getObjCClassType());
2386   QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2387                                                 &ArgTys[0], ArgTys.size());
2388   GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2389                                                    SourceLocation(),
2390                                                    SourceLocation(),
2391                                                    getSuperClassIdent,
2392                                                    getClassType, 0,
2393                                                    SC_Extern,
2394                                                    SC_None,
2395                                                    false);
2396 }
2397
2398 // SynthGetMetaClassFunctionDecl - id objc_getMetaClass(const char *name);
2399 void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2400   IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
2401   SmallVector<QualType, 16> ArgTys;
2402   ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2403   QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(),
2404                                                 &ArgTys[0], ArgTys.size());
2405   GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2406                                               SourceLocation(),
2407                                               SourceLocation(),
2408                                               getClassIdent, getClassType, 0,
2409                                               SC_Extern,
2410                                               SC_None, false);
2411 }
2412
2413 Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
2414   QualType strType = getConstantStringStructType();
2415
2416   std::string S = "__NSConstantStringImpl_";
2417
2418   std::string tmpName = InFileName;
2419   unsigned i;
2420   for (i=0; i < tmpName.length(); i++) {
2421     char c = tmpName.at(i);
2422     // replace any non alphanumeric characters with '_'.
2423     if (!isalpha(c) && (c < '0' || c > '9'))
2424       tmpName[i] = '_';
2425   }
2426   S += tmpName;
2427   S += "_";
2428   S += utostr(NumObjCStringLiterals++);
2429
2430   Preamble += "static __NSConstantStringImpl " + S;
2431   Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2432   Preamble += "0x000007c8,"; // utf8_str
2433   // The pretty printer for StringLiteral handles escape characters properly.
2434   std::string prettyBufS;
2435   llvm::raw_string_ostream prettyBuf(prettyBufS);
2436   Exp->getString()->printPretty(prettyBuf, *Context, 0,
2437                                 PrintingPolicy(LangOpts));
2438   Preamble += prettyBuf.str();
2439   Preamble += ",";
2440   Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
2441
2442   VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
2443                                    SourceLocation(), &Context->Idents.get(S),
2444                                    strType, 0, SC_Static, SC_None);
2445   DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
2446                                                SourceLocation());
2447   Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
2448                                  Context->getPointerType(DRE->getType()),
2449                                            VK_RValue, OK_Ordinary,
2450                                            SourceLocation());
2451   // cast to NSConstantString *
2452   CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
2453                                             CK_CPointerToObjCPointerCast, Unop);
2454   ReplaceStmt(Exp, cast);
2455   // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
2456   return cast;
2457 }
2458
2459 Stmt *RewriteModernObjC::RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp) {
2460   unsigned IntSize =
2461     static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
2462   
2463   Expr *FlagExp = IntegerLiteral::Create(*Context, 
2464                                          llvm::APInt(IntSize, Exp->getValue()), 
2465                                          Context->IntTy, Exp->getLocation());
2466   CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
2467                                             CK_BitCast, FlagExp);
2468   ParenExpr *PE = new (Context) ParenExpr(Exp->getLocation(), Exp->getExprLoc(), 
2469                                           cast);
2470   ReplaceStmt(Exp, PE);
2471   return PE;
2472 }
2473
2474 Stmt *RewriteModernObjC::RewriteObjCNumericLiteralExpr(ObjCNumericLiteral *Exp) {
2475   // synthesize declaration of helper functions needed in this routine.
2476   if (!SelGetUidFunctionDecl)
2477     SynthSelGetUidFunctionDecl();
2478   // use objc_msgSend() for all.
2479   if (!MsgSendFunctionDecl)
2480     SynthMsgSendFunctionDecl();
2481   if (!GetClassFunctionDecl)
2482     SynthGetClassFunctionDecl();
2483   
2484   FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
2485   SourceLocation StartLoc = Exp->getLocStart();
2486   SourceLocation EndLoc = Exp->getLocEnd();
2487   
2488   // Synthesize a call to objc_msgSend().
2489   SmallVector<Expr*, 4> MsgExprs;
2490   SmallVector<Expr*, 4> ClsExprs;
2491   QualType argType = Context->getPointerType(Context->CharTy);
2492   QualType expType = Exp->getType();
2493   
2494   // Create a call to objc_getClass("NSNumber"). It will be th 1st argument.
2495   ObjCInterfaceDecl *Class = 
2496     expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
2497   
2498   IdentifierInfo *clsName = Class->getIdentifier();
2499   ClsExprs.push_back(StringLiteral::Create(*Context,
2500                                            clsName->getName(),
2501                                            StringLiteral::Ascii, false,
2502                                            argType, SourceLocation()));
2503   CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
2504                                                &ClsExprs[0],
2505                                                ClsExprs.size(), 
2506                                                StartLoc, EndLoc);
2507   MsgExprs.push_back(Cls);
2508   
2509   // Create a call to sel_registerName("numberWithBool:"), etc.
2510   // it will be the 2nd argument.
2511   SmallVector<Expr*, 4> SelExprs;
2512   ObjCMethodDecl *NumericMethod = Exp->getObjCNumericLiteralMethod();
2513   SelExprs.push_back(StringLiteral::Create(*Context,
2514                                            NumericMethod->getSelector().getAsString(),
2515                                            StringLiteral::Ascii, false,
2516                                            argType, SourceLocation()));
2517   CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2518                                                   &SelExprs[0], SelExprs.size(),
2519                                                   StartLoc, EndLoc);
2520   MsgExprs.push_back(SelExp);
2521   
2522   // User provided numeric literal is the 3rd, and last, argument.
2523   Expr *userExpr  = Exp->getNumber();
2524   if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
2525     QualType type = ICE->getType();
2526     const Expr *SubExpr = ICE->IgnoreParenImpCasts();
2527     CastKind CK = CK_BitCast;
2528     if (SubExpr->getType()->isIntegralType(*Context) && type->isBooleanType())
2529       CK = CK_IntegralToBoolean;
2530     userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
2531   }
2532   MsgExprs.push_back(userExpr);
2533   
2534   SmallVector<QualType, 4> ArgTypes;
2535   ArgTypes.push_back(Context->getObjCIdType());
2536   ArgTypes.push_back(Context->getObjCSelType());
2537   for (ObjCMethodDecl::param_iterator PI = NumericMethod->param_begin(),
2538        E = NumericMethod->param_end(); PI != E; ++PI)
2539     ArgTypes.push_back((*PI)->getType());
2540     
2541   QualType returnType = Exp->getType();
2542   // Get the type, we will need to reference it in a couple spots.
2543   QualType msgSendType = MsgSendFlavor->getType();
2544   
2545   // Create a reference to the objc_msgSend() declaration.
2546   DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
2547                                                VK_LValue, SourceLocation());
2548   
2549   CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
2550                                   Context->getPointerType(Context->VoidTy),
2551                                   CK_BitCast, DRE);
2552   
2553   // Now do the "normal" pointer to function cast.
2554   QualType castType =
2555     getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
2556                           NumericMethod->isVariadic());
2557   castType = Context->getPointerType(castType);
2558   cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2559                                   cast);
2560   
2561   // Don't forget the parens to enforce the proper binding.
2562   ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
2563   
2564   const FunctionType *FT = msgSendType->getAs<FunctionType>();
2565   CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
2566                                         MsgExprs.size(),
2567                                         FT->getResultType(), VK_RValue,
2568                                         EndLoc);
2569   ReplaceStmt(Exp, CE);
2570   return CE;
2571 }
2572
2573 Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
2574   // synthesize declaration of helper functions needed in this routine.
2575   if (!SelGetUidFunctionDecl)
2576     SynthSelGetUidFunctionDecl();
2577   // use objc_msgSend() for all.
2578   if (!MsgSendFunctionDecl)
2579     SynthMsgSendFunctionDecl();
2580   if (!GetClassFunctionDecl)
2581     SynthGetClassFunctionDecl();
2582   
2583   FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
2584   SourceLocation StartLoc = Exp->getLocStart();
2585   SourceLocation EndLoc = Exp->getLocEnd();
2586   
2587   // Build the expression: __NSContainer_literal(int, ...).arr
2588   QualType IntQT = Context->IntTy;
2589   QualType NSArrayFType =
2590     getSimpleFunctionType(Context->VoidTy, &IntQT, 1, true);
2591   std::string NSArrayFName("__NSContainer_literal");
2592   FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2593   DeclRefExpr *NSArrayDRE = 
2594     new (Context) DeclRefExpr(NSArrayFD, false, NSArrayFType, VK_RValue,
2595                               SourceLocation());
2596
2597   SmallVector<Expr*, 16> InitExprs;
2598   unsigned NumElements = Exp->getNumElements();
2599   unsigned UnsignedIntSize = 
2600     static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2601   Expr *count = IntegerLiteral::Create(*Context,
2602                                        llvm::APInt(UnsignedIntSize, NumElements),
2603                                        Context->UnsignedIntTy, SourceLocation());
2604   InitExprs.push_back(count);
2605   for (unsigned i = 0; i < NumElements; i++)
2606     InitExprs.push_back(Exp->getElement(i));
2607   Expr *NSArrayCallExpr = 
2608     new (Context) CallExpr(*Context, NSArrayDRE, &InitExprs[0], InitExprs.size(),
2609                            NSArrayFType, VK_LValue, SourceLocation());
2610   
2611   FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(),
2612                                     SourceLocation(),
2613                                     &Context->Idents.get("arr"),
2614                                     Context->getPointerType(Context->VoidPtrTy), 0,
2615                                     /*BitWidth=*/0, /*Mutable=*/true,
2616                                     /*HasInit=*/false);
2617   MemberExpr *ArrayLiteralME = 
2618     new (Context) MemberExpr(NSArrayCallExpr, false, ARRFD, 
2619                              SourceLocation(),
2620                              ARRFD->getType(), VK_LValue,
2621                              OK_Ordinary);
2622   QualType ConstIdT = Context->getObjCIdType().withConst();
2623   CStyleCastExpr * ArrayLiteralObjects = 
2624     NoTypeInfoCStyleCastExpr(Context, 
2625                              Context->getPointerType(ConstIdT),
2626                              CK_BitCast,
2627                              ArrayLiteralME);
2628   
2629   // Synthesize a call to objc_msgSend().
2630   SmallVector<Expr*, 32> MsgExprs;
2631   SmallVector<Expr*, 4> ClsExprs;
2632   QualType argType = Context->getPointerType(Context->CharTy);
2633   QualType expType = Exp->getType();
2634   
2635   // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
2636   ObjCInterfaceDecl *Class = 
2637     expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
2638   
2639   IdentifierInfo *clsName = Class->getIdentifier();
2640   ClsExprs.push_back(StringLiteral::Create(*Context,
2641                                            clsName->getName(),
2642                                            StringLiteral::Ascii, false,
2643                                            argType, SourceLocation()));
2644   CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
2645                                                &ClsExprs[0],
2646                                                ClsExprs.size(), 
2647                                                StartLoc, EndLoc);
2648   MsgExprs.push_back(Cls);
2649   
2650   // Create a call to sel_registerName("arrayWithObjects:count:").
2651   // it will be the 2nd argument.
2652   SmallVector<Expr*, 4> SelExprs;
2653   ObjCMethodDecl *ArrayMethod = Exp->getArrayWithObjectsMethod();
2654   SelExprs.push_back(StringLiteral::Create(*Context,
2655                                            ArrayMethod->getSelector().getAsString(),
2656                                            StringLiteral::Ascii, false,
2657                                            argType, SourceLocation()));
2658   CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2659                                                   &SelExprs[0], SelExprs.size(),
2660                                                   StartLoc, EndLoc);
2661   MsgExprs.push_back(SelExp);
2662   
2663   // (const id [])objects
2664   MsgExprs.push_back(ArrayLiteralObjects);
2665   
2666   // (NSUInteger)cnt
2667   Expr *cnt = IntegerLiteral::Create(*Context,
2668                                      llvm::APInt(UnsignedIntSize, NumElements),
2669                                      Context->UnsignedIntTy, SourceLocation());
2670   MsgExprs.push_back(cnt);
2671   
2672   
2673   SmallVector<QualType, 4> ArgTypes;
2674   ArgTypes.push_back(Context->getObjCIdType());
2675   ArgTypes.push_back(Context->getObjCSelType());
2676   for (ObjCMethodDecl::param_iterator PI = ArrayMethod->param_begin(),
2677        E = ArrayMethod->param_end(); PI != E; ++PI)
2678     ArgTypes.push_back((*PI)->getType());
2679   
2680   QualType returnType = Exp->getType();
2681   // Get the type, we will need to reference it in a couple spots.
2682   QualType msgSendType = MsgSendFlavor->getType();
2683   
2684   // Create a reference to the objc_msgSend() declaration.
2685   DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
2686                                                VK_LValue, SourceLocation());
2687   
2688   CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
2689                                             Context->getPointerType(Context->VoidTy),
2690                                             CK_BitCast, DRE);
2691   
2692   // Now do the "normal" pointer to function cast.
2693   QualType castType =
2694   getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
2695                         ArrayMethod->isVariadic());
2696   castType = Context->getPointerType(castType);
2697   cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2698                                   cast);
2699   
2700   // Don't forget the parens to enforce the proper binding.
2701   ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
2702   
2703   const FunctionType *FT = msgSendType->getAs<FunctionType>();
2704   CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
2705                                         MsgExprs.size(),
2706                                         FT->getResultType(), VK_RValue,
2707                                         EndLoc);
2708   ReplaceStmt(Exp, CE);
2709   return CE;
2710 }
2711
2712 Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp) {
2713   // synthesize declaration of helper functions needed in this routine.
2714   if (!SelGetUidFunctionDecl)
2715     SynthSelGetUidFunctionDecl();
2716   // use objc_msgSend() for all.
2717   if (!MsgSendFunctionDecl)
2718     SynthMsgSendFunctionDecl();
2719   if (!GetClassFunctionDecl)
2720     SynthGetClassFunctionDecl();
2721   
2722   FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
2723   SourceLocation StartLoc = Exp->getLocStart();
2724   SourceLocation EndLoc = Exp->getLocEnd();
2725   
2726   // Build the expression: __NSContainer_literal(int, ...).arr
2727   QualType IntQT = Context->IntTy;
2728   QualType NSDictFType =
2729     getSimpleFunctionType(Context->VoidTy, &IntQT, 1, true);
2730   std::string NSDictFName("__NSContainer_literal");
2731   FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2732   DeclRefExpr *NSDictDRE = 
2733     new (Context) DeclRefExpr(NSDictFD, false, NSDictFType, VK_RValue,
2734                               SourceLocation());
2735   
2736   SmallVector<Expr*, 16> KeyExprs;
2737   SmallVector<Expr*, 16> ValueExprs;
2738   
2739   unsigned NumElements = Exp->getNumElements();
2740   unsigned UnsignedIntSize = 
2741     static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2742   Expr *count = IntegerLiteral::Create(*Context,
2743                                        llvm::APInt(UnsignedIntSize, NumElements),
2744                                        Context->UnsignedIntTy, SourceLocation());
2745   KeyExprs.push_back(count);
2746   ValueExprs.push_back(count);
2747   for (unsigned i = 0; i < NumElements; i++) {
2748     ObjCDictionaryElement Element = Exp->getKeyValueElement(i);
2749     KeyExprs.push_back(Element.Key);
2750     ValueExprs.push_back(Element.Value);
2751   }
2752   
2753   // (const id [])objects
2754   Expr *NSValueCallExpr = 
2755     new (Context) CallExpr(*Context, NSDictDRE, &ValueExprs[0], ValueExprs.size(),
2756                            NSDictFType, VK_LValue, SourceLocation());
2757   
2758   FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(),
2759                                        SourceLocation(),
2760                                        &Context->Idents.get("arr"),
2761                                        Context->getPointerType(Context->VoidPtrTy), 0,
2762                                        /*BitWidth=*/0, /*Mutable=*/true,
2763                                        /*HasInit=*/false);
2764   MemberExpr *DictLiteralValueME = 
2765     new (Context) MemberExpr(NSValueCallExpr, false, ARRFD, 
2766                              SourceLocation(),
2767                              ARRFD->getType(), VK_LValue,
2768                              OK_Ordinary);
2769   QualType ConstIdT = Context->getObjCIdType().withConst();
2770   CStyleCastExpr * DictValueObjects = 
2771     NoTypeInfoCStyleCastExpr(Context, 
2772                              Context->getPointerType(ConstIdT),
2773                              CK_BitCast,
2774                              DictLiteralValueME);
2775   // (const id <NSCopying> [])keys
2776   Expr *NSKeyCallExpr = 
2777     new (Context) CallExpr(*Context, NSDictDRE, &KeyExprs[0], KeyExprs.size(),
2778                            NSDictFType, VK_LValue, SourceLocation());
2779   
2780   MemberExpr *DictLiteralKeyME = 
2781     new (Context) MemberExpr(NSKeyCallExpr, false, ARRFD, 
2782                              SourceLocation(),
2783                              ARRFD->getType(), VK_LValue,
2784                              OK_Ordinary);
2785   
2786   CStyleCastExpr * DictKeyObjects = 
2787     NoTypeInfoCStyleCastExpr(Context, 
2788                              Context->getPointerType(ConstIdT),
2789                              CK_BitCast,
2790                              DictLiteralKeyME);
2791   
2792   
2793   
2794   // Synthesize a call to objc_msgSend().
2795   SmallVector<Expr*, 32> MsgExprs;
2796   SmallVector<Expr*, 4> ClsExprs;
2797   QualType argType = Context->getPointerType(Context->CharTy);
2798   QualType expType = Exp->getType();
2799   
2800   // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
2801   ObjCInterfaceDecl *Class = 
2802   expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
2803   
2804   IdentifierInfo *clsName = Class->getIdentifier();
2805   ClsExprs.push_back(StringLiteral::Create(*Context,
2806                                            clsName->getName(),
2807                                            StringLiteral::Ascii, false,
2808                                            argType, SourceLocation()));
2809   CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
2810                                                &ClsExprs[0],
2811                                                ClsExprs.size(), 
2812                                                StartLoc, EndLoc);
2813   MsgExprs.push_back(Cls);
2814   
2815   // Create a call to sel_registerName("arrayWithObjects:count:").
2816   // it will be the 2nd argument.
2817   SmallVector<Expr*, 4> SelExprs;
2818   ObjCMethodDecl *DictMethod = Exp->getDictWithObjectsMethod();
2819   SelExprs.push_back(StringLiteral::Create(*Context,
2820                                            DictMethod->getSelector().getAsString(),
2821                                            StringLiteral::Ascii, false,
2822                                            argType, SourceLocation()));
2823   CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2824                                                   &SelExprs[0], SelExprs.size(),
2825                                                   StartLoc, EndLoc);
2826   MsgExprs.push_back(SelExp);
2827   
2828   // (const id [])objects
2829   MsgExprs.push_back(DictValueObjects);
2830   
2831   // (const id <NSCopying> [])keys
2832   MsgExprs.push_back(DictKeyObjects);
2833   
2834   // (NSUInteger)cnt
2835   Expr *cnt = IntegerLiteral::Create(*Context,
2836                                      llvm::APInt(UnsignedIntSize, NumElements),
2837                                      Context->UnsignedIntTy, SourceLocation());
2838   MsgExprs.push_back(cnt);
2839   
2840   
2841   SmallVector<QualType, 8> ArgTypes;
2842   ArgTypes.push_back(Context->getObjCIdType());
2843   ArgTypes.push_back(Context->getObjCSelType());
2844   for (ObjCMethodDecl::param_iterator PI = DictMethod->param_begin(),
2845        E = DictMethod->param_end(); PI != E; ++PI) {
2846     QualType T = (*PI)->getType();
2847     if (const PointerType* PT = T->getAs<PointerType>()) {
2848       QualType PointeeTy = PT->getPointeeType();
2849       convertToUnqualifiedObjCType(PointeeTy);
2850       T = Context->getPointerType(PointeeTy);
2851     }
2852     ArgTypes.push_back(T);
2853   }
2854   
2855   QualType returnType = Exp->getType();
2856   // Get the type, we will need to reference it in a couple spots.
2857   QualType msgSendType = MsgSendFlavor->getType();
2858   
2859   // Create a reference to the objc_msgSend() declaration.
2860   DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
2861                                                VK_LValue, SourceLocation());
2862   
2863   CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
2864                                             Context->getPointerType(Context->VoidTy),
2865                                             CK_BitCast, DRE);
2866   
2867   // Now do the "normal" pointer to function cast.
2868   QualType castType =
2869   getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
2870                         DictMethod->isVariadic());
2871   castType = Context->getPointerType(castType);
2872   cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2873                                   cast);
2874   
2875   // Don't forget the parens to enforce the proper binding.
2876   ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
2877   
2878   const FunctionType *FT = msgSendType->getAs<FunctionType>();
2879   CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
2880                                         MsgExprs.size(),
2881                                         FT->getResultType(), VK_RValue,
2882                                         EndLoc);
2883   ReplaceStmt(Exp, CE);
2884   return CE;
2885 }
2886
2887 // struct __rw_objc_super { 
2888 //   struct objc_object *object; struct objc_object *superClass; 
2889 // };
2890 QualType RewriteModernObjC::getSuperStructType() {
2891   if (!SuperStructDecl) {
2892     SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
2893                                          SourceLocation(), SourceLocation(),
2894                                          &Context->Idents.get("__rw_objc_super"));
2895     QualType FieldTypes[2];
2896
2897     // struct objc_object *object;
2898     FieldTypes[0] = Context->getObjCIdType();
2899     // struct objc_object *superClass;
2900     FieldTypes[1] = Context->getObjCIdType();
2901
2902     // Create fields
2903     for (unsigned i = 0; i < 2; ++i) {
2904       SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
2905                                                  SourceLocation(),
2906                                                  SourceLocation(), 0,
2907                                                  FieldTypes[i], 0,
2908                                                  /*BitWidth=*/0,
2909                                                  /*Mutable=*/false,
2910                                                  /*HasInit=*/false));
2911     }
2912
2913     SuperStructDecl->completeDefinition();
2914   }
2915   return Context->getTagDeclType(SuperStructDecl);
2916 }
2917
2918 QualType RewriteModernObjC::getConstantStringStructType() {
2919   if (!ConstantStringDecl) {
2920     ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
2921                                             SourceLocation(), SourceLocation(),
2922                          &Context->Idents.get("__NSConstantStringImpl"));
2923     QualType FieldTypes[4];
2924
2925     // struct objc_object *receiver;
2926     FieldTypes[0] = Context->getObjCIdType();
2927     // int flags;
2928     FieldTypes[1] = Context->IntTy;
2929     // char *str;
2930     FieldTypes[2] = Context->getPointerType(Context->CharTy);
2931     // long length;
2932     FieldTypes[3] = Context->LongTy;
2933
2934     // Create fields
2935     for (unsigned i = 0; i < 4; ++i) {
2936       ConstantStringDecl->addDecl(FieldDecl::Create(*Context,
2937                                                     ConstantStringDecl,
2938                                                     SourceLocation(),
2939                                                     SourceLocation(), 0,
2940                                                     FieldTypes[i], 0,
2941                                                     /*BitWidth=*/0,
2942                                                     /*Mutable=*/true,
2943                                                     /*HasInit=*/false));
2944     }
2945
2946     ConstantStringDecl->completeDefinition();
2947   }
2948   return Context->getTagDeclType(ConstantStringDecl);
2949 }
2950
2951 Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
2952                                     SourceLocation StartLoc,
2953                                     SourceLocation EndLoc) {
2954   if (!SelGetUidFunctionDecl)
2955     SynthSelGetUidFunctionDecl();
2956   if (!MsgSendFunctionDecl)
2957     SynthMsgSendFunctionDecl();
2958   if (!MsgSendSuperFunctionDecl)
2959     SynthMsgSendSuperFunctionDecl();
2960   if (!MsgSendStretFunctionDecl)
2961     SynthMsgSendStretFunctionDecl();
2962   if (!MsgSendSuperStretFunctionDecl)
2963     SynthMsgSendSuperStretFunctionDecl();
2964   if (!MsgSendFpretFunctionDecl)
2965     SynthMsgSendFpretFunctionDecl();
2966   if (!GetClassFunctionDecl)
2967     SynthGetClassFunctionDecl();
2968   if (!GetSuperClassFunctionDecl)
2969     SynthGetSuperClassFunctionDecl();
2970   if (!GetMetaClassFunctionDecl)
2971     SynthGetMetaClassFunctionDecl();
2972
2973   // default to objc_msgSend().
2974   FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
2975   // May need to use objc_msgSend_stret() as well.
2976   FunctionDecl *MsgSendStretFlavor = 0;
2977   if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
2978     QualType resultType = mDecl->getResultType();
2979     if (resultType->isRecordType())
2980       MsgSendStretFlavor = MsgSendStretFunctionDecl;
2981     else if (resultType->isRealFloatingType())
2982       MsgSendFlavor = MsgSendFpretFunctionDecl;
2983   }
2984
2985   // Synthesize a call to objc_msgSend().
2986   SmallVector<Expr*, 8> MsgExprs;
2987   switch (Exp->getReceiverKind()) {
2988   case ObjCMessageExpr::SuperClass: {
2989     MsgSendFlavor = MsgSendSuperFunctionDecl;
2990     if (MsgSendStretFlavor)
2991       MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
2992     assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
2993
2994     ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
2995
2996     SmallVector<Expr*, 4> InitExprs;
2997
2998     // set the receiver to self, the first argument to all methods.
2999     InitExprs.push_back(
3000       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3001                                CK_BitCast,
3002                    new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
3003                                              false,
3004                                              Context->getObjCIdType(),
3005                                              VK_RValue,
3006                                              SourceLocation()))
3007                         ); // set the 'receiver'.
3008
3009     // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
3010     SmallVector<Expr*, 8> ClsExprs;
3011     QualType argType = Context->getPointerType(Context->CharTy);
3012     ClsExprs.push_back(StringLiteral::Create(*Context,
3013                                    ClassDecl->getIdentifier()->getName(),
3014                                    StringLiteral::Ascii, false,
3015                                    argType, SourceLocation()));
3016     CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3017                                                  &ClsExprs[0],
3018                                                  ClsExprs.size(),
3019                                                  StartLoc,
3020                                                  EndLoc);
3021     // (Class)objc_getClass("CurrentClass")
3022     CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
3023                                              Context->getObjCClassType(),
3024                                              CK_BitCast, Cls);
3025     ClsExprs.clear();
3026     ClsExprs.push_back(ArgExpr);
3027     Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
3028                                        &ClsExprs[0], ClsExprs.size(),
3029                                        StartLoc, EndLoc);
3030     
3031     // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
3032     // To turn off a warning, type-cast to 'id'
3033     InitExprs.push_back( // set 'super class', using class_getSuperclass().
3034                         NoTypeInfoCStyleCastExpr(Context,
3035                                                  Context->getObjCIdType(),
3036                                                  CK_BitCast, Cls));
3037     // struct __rw_objc_super
3038     QualType superType = getSuperStructType();
3039     Expr *SuperRep;
3040
3041     if (LangOpts.MicrosoftExt) {
3042       SynthSuperContructorFunctionDecl();
3043       // Simulate a contructor call...
3044       DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
3045                                                    false, superType, VK_LValue,
3046                                                    SourceLocation());
3047       SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
3048                                         InitExprs.size(),
3049                                         superType, VK_LValue,
3050                                         SourceLocation());
3051       // The code for super is a little tricky to prevent collision with
3052       // the structure definition in the header. The rewriter has it's own
3053       // internal definition (__rw_objc_super) that is uses. This is why
3054       // we need the cast below. For example:
3055       // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
3056       //
3057       SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
3058                                Context->getPointerType(SuperRep->getType()),
3059                                              VK_RValue, OK_Ordinary,
3060                                              SourceLocation());
3061       SuperRep = NoTypeInfoCStyleCastExpr(Context,
3062                                           Context->getPointerType(superType),
3063                                           CK_BitCast, SuperRep);
3064     } else {
3065       // (struct __rw_objc_super) { <exprs from above> }
3066       InitListExpr *ILE =
3067         new (Context) InitListExpr(*Context, SourceLocation(),
3068                                    &InitExprs[0], InitExprs.size(),
3069                                    SourceLocation());
3070       TypeSourceInfo *superTInfo
3071         = Context->getTrivialTypeSourceInfo(superType);
3072       SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
3073                                                    superType, VK_LValue,
3074                                                    ILE, false);
3075       // struct __rw_objc_super *
3076       SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
3077                                Context->getPointerType(SuperRep->getType()),
3078                                              VK_RValue, OK_Ordinary,
3079                                              SourceLocation());
3080     }
3081     MsgExprs.push_back(SuperRep);
3082     break;
3083   }
3084
3085   case ObjCMessageExpr::Class: {
3086     SmallVector<Expr*, 8> ClsExprs;
3087     QualType argType = Context->getPointerType(Context->CharTy);
3088     ObjCInterfaceDecl *Class
3089       = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
3090     IdentifierInfo *clsName = Class->getIdentifier();
3091     ClsExprs.push_back(StringLiteral::Create(*Context,
3092                                              clsName->getName(),
3093                                              StringLiteral::Ascii, false,
3094                                              argType, SourceLocation()));
3095     CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
3096                                                  &ClsExprs[0],
3097                                                  ClsExprs.size(), 
3098                                                  StartLoc, EndLoc);
3099     MsgExprs.push_back(Cls);
3100     break;
3101   }
3102
3103   case ObjCMessageExpr::SuperInstance:{
3104     MsgSendFlavor = MsgSendSuperFunctionDecl;
3105     if (MsgSendStretFlavor)
3106       MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3107     assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
3108     ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
3109     SmallVector<Expr*, 4> InitExprs;
3110
3111     InitExprs.push_back(
3112       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3113                                CK_BitCast,
3114                    new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
3115                                              false,
3116                                              Context->getObjCIdType(),
3117                                              VK_RValue, SourceLocation()))
3118                         ); // set the 'receiver'.
3119     
3120     // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
3121     SmallVector<Expr*, 8> ClsExprs;
3122     QualType argType = Context->getPointerType(Context->CharTy);
3123     ClsExprs.push_back(StringLiteral::Create(*Context,
3124                                    ClassDecl->getIdentifier()->getName(),
3125                                    StringLiteral::Ascii, false, argType,
3126                                    SourceLocation()));
3127     CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
3128                                                  &ClsExprs[0],
3129                                                  ClsExprs.size(), 
3130                                                  StartLoc, EndLoc);
3131     // (Class)objc_getClass("CurrentClass")
3132     CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
3133                                                  Context->getObjCClassType(),
3134                                                  CK_BitCast, Cls);
3135     ClsExprs.clear();
3136     ClsExprs.push_back(ArgExpr);
3137     Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
3138                                        &ClsExprs[0], ClsExprs.size(),
3139                                        StartLoc, EndLoc);
3140     
3141     // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
3142     // To turn off a warning, type-cast to 'id'
3143     InitExprs.push_back(
3144       // set 'super class', using class_getSuperclass().
3145       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3146                                CK_BitCast, Cls));
3147     // struct __rw_objc_super
3148     QualType superType = getSuperStructType();
3149     Expr *SuperRep;
3150
3151     if (LangOpts.MicrosoftExt) {
3152       SynthSuperContructorFunctionDecl();
3153       // Simulate a contructor call...
3154       DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
3155                                                    false, superType, VK_LValue,
3156                                                    SourceLocation());
3157       SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
3158                                         InitExprs.size(),
3159                                         superType, VK_LValue, SourceLocation());
3160       // The code for super is a little tricky to prevent collision with
3161       // the structure definition in the header. The rewriter has it's own
3162       // internal definition (__rw_objc_super) that is uses. This is why
3163       // we need the cast below. For example:
3164       // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
3165       //
3166       SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
3167                                Context->getPointerType(SuperRep->getType()),
3168                                VK_RValue, OK_Ordinary,
3169                                SourceLocation());
3170       SuperRep = NoTypeInfoCStyleCastExpr(Context,
3171                                Context->getPointerType(superType),
3172                                CK_BitCast, SuperRep);
3173     } else {
3174       // (struct __rw_objc_super) { <exprs from above> }
3175       InitListExpr *ILE =
3176         new (Context) InitListExpr(*Context, SourceLocation(),
3177                                    &InitExprs[0], InitExprs.size(),
3178                                    SourceLocation());
3179       TypeSourceInfo *superTInfo
3180         = Context->getTrivialTypeSourceInfo(superType);
3181       SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
3182                                                    superType, VK_RValue, ILE,
3183                                                    false);
3184     }
3185     MsgExprs.push_back(SuperRep);
3186     break;
3187   }
3188
3189   case ObjCMessageExpr::Instance: {
3190     // Remove all type-casts because it may contain objc-style types; e.g.
3191     // Foo<Proto> *.
3192     Expr *recExpr = Exp->getInstanceReceiver();
3193     while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
3194       recExpr = CE->getSubExpr();
3195     CastKind CK = recExpr->getType()->isObjCObjectPointerType()
3196                     ? CK_BitCast : recExpr->getType()->isBlockPointerType()
3197                                      ? CK_BlockPointerToObjCPointerCast
3198                                      : CK_CPointerToObjCPointerCast;
3199
3200     recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3201                                        CK, recExpr);
3202     MsgExprs.push_back(recExpr);
3203     break;
3204   }
3205   }
3206
3207   // Create a call to sel_registerName("selName"), it will be the 2nd argument.
3208   SmallVector<Expr*, 8> SelExprs;
3209   QualType argType = Context->getPointerType(Context->CharTy);
3210   SelExprs.push_back(StringLiteral::Create(*Context,
3211                                        Exp->getSelector().getAsString(),
3212                                        StringLiteral::Ascii, false,
3213                                        argType, SourceLocation()));
3214   CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3215                                                  &SelExprs[0], SelExprs.size(),
3216                                                   StartLoc,
3217                                                   EndLoc);
3218   MsgExprs.push_back(SelExp);
3219
3220   // Now push any user supplied arguments.
3221   for (unsigned i = 0; i < Exp->getNumArgs(); i++) {
3222     Expr *userExpr = Exp->getArg(i);
3223     // Make all implicit casts explicit...ICE comes in handy:-)
3224     if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
3225       // Reuse the ICE type, it is exactly what the doctor ordered.
3226       QualType type = ICE->getType();
3227       if (needToScanForQualifiers(type))
3228         type = Context->getObjCIdType();
3229       // Make sure we convert "type (^)(...)" to "type (*)(...)".
3230       (void)convertBlockPointerToFunctionPointer(type);
3231       const Expr *SubExpr = ICE->IgnoreParenImpCasts();
3232       CastKind CK;
3233       if (SubExpr->getType()->isIntegralType(*Context) && 
3234           type->isBooleanType()) {
3235         CK = CK_IntegralToBoolean;
3236       } else if (type->isObjCObjectPointerType()) {
3237         if (SubExpr->getType()->isBlockPointerType()) {
3238           CK = CK_BlockPointerToObjCPointerCast;
3239         } else if (SubExpr->getType()->isPointerType()) {
3240           CK = CK_CPointerToObjCPointerCast;
3241         } else {
3242           CK = CK_BitCast;
3243         }
3244       } else {
3245         CK = CK_BitCast;
3246       }
3247
3248       userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
3249     }
3250     // Make id<P...> cast into an 'id' cast.
3251     else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3252       if (CE->getType()->isObjCQualifiedIdType()) {
3253         while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3254           userExpr = CE->getSubExpr();
3255         CastKind CK;
3256         if (userExpr->getType()->isIntegralType(*Context)) {
3257           CK = CK_IntegralToPointer;
3258         } else if (userExpr->getType()->isBlockPointerType()) {
3259           CK = CK_BlockPointerToObjCPointerCast;
3260         } else if (userExpr->getType()->isPointerType()) {
3261           CK = CK_CPointerToObjCPointerCast;
3262         } else {
3263           CK = CK_BitCast;
3264         }
3265         userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3266                                             CK, userExpr);
3267       }
3268     }
3269     MsgExprs.push_back(userExpr);
3270     // We've transferred the ownership to MsgExprs. For now, we *don't* null
3271     // out the argument in the original expression (since we aren't deleting
3272     // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info.
3273     //Exp->setArg(i, 0);
3274   }
3275   // Generate the funky cast.
3276   CastExpr *cast;
3277   SmallVector<QualType, 8> ArgTypes;
3278   QualType returnType;
3279
3280   // Push 'id' and 'SEL', the 2 implicit arguments.
3281   if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3282     ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
3283   else
3284     ArgTypes.push_back(Context->getObjCIdType());
3285   ArgTypes.push_back(Context->getObjCSelType());
3286   if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) {
3287     // Push any user argument types.
3288     for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
3289          E = OMD->param_end(); PI != E; ++PI) {
3290       QualType t = (*PI)->getType()->isObjCQualifiedIdType()
3291                      ? Context->getObjCIdType()
3292                      : (*PI)->getType();
3293       // Make sure we convert "t (^)(...)" to "t (*)(...)".
3294       (void)convertBlockPointerToFunctionPointer(t);
3295       ArgTypes.push_back(t);
3296     }
3297     returnType = Exp->getType();
3298     convertToUnqualifiedObjCType(returnType);
3299     (void)convertBlockPointerToFunctionPointer(returnType);
3300   } else {
3301     returnType = Context->getObjCIdType();
3302   }
3303   // Get the type, we will need to reference it in a couple spots.
3304   QualType msgSendType = MsgSendFlavor->getType();
3305
3306   // Create a reference to the objc_msgSend() declaration.
3307   DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
3308                                                VK_LValue, SourceLocation());
3309
3310   // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
3311   // If we don't do this cast, we get the following bizarre warning/note:
3312   // xx.m:13: warning: function called through a non-compatible type
3313   // xx.m:13: note: if this code is reached, the program will abort
3314   cast = NoTypeInfoCStyleCastExpr(Context,
3315                                   Context->getPointerType(Context->VoidTy),
3316                                   CK_BitCast, DRE);
3317
3318   // Now do the "normal" pointer to function cast.
3319   QualType castType =
3320     getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
3321       // If we don't have a method decl, force a variadic cast.
3322       Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true);
3323   castType = Context->getPointerType(castType);
3324   cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
3325                                   cast);
3326
3327   // Don't forget the parens to enforce the proper binding.
3328   ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
3329
3330   const FunctionType *FT = msgSendType->getAs<FunctionType>();
3331   CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
3332                                         MsgExprs.size(),
3333                                         FT->getResultType(), VK_RValue,
3334                                         EndLoc);
3335   Stmt *ReplacingStmt = CE;
3336   if (MsgSendStretFlavor) {
3337     // We have the method which returns a struct/union. Must also generate
3338     // call to objc_msgSend_stret and hang both varieties on a conditional
3339     // expression which dictate which one to envoke depending on size of
3340     // method's return type.
3341
3342     // Create a reference to the objc_msgSend_stret() declaration.
3343     DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor,
3344                                                    false, msgSendType,
3345                                                    VK_LValue, SourceLocation());
3346     // Need to cast objc_msgSend_stret to "void *" (see above comment).
3347     cast = NoTypeInfoCStyleCastExpr(Context,
3348                                     Context->getPointerType(Context->VoidTy),
3349                                     CK_BitCast, STDRE);
3350     // Now do the "normal" pointer to function cast.
3351     castType = getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
3352       Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false);
3353     castType = Context->getPointerType(castType);
3354     cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
3355                                     cast);
3356
3357     // Don't forget the parens to enforce the proper binding.
3358     PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast);
3359
3360     FT = msgSendType->getAs<FunctionType>();
3361     CallExpr *STCE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
3362                                             MsgExprs.size(),
3363                                             FT->getResultType(), VK_RValue,
3364                                             SourceLocation());
3365
3366     // Build sizeof(returnType)
3367     UnaryExprOrTypeTraitExpr *sizeofExpr =
3368        new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf,
3369                                  Context->getTrivialTypeSourceInfo(returnType),
3370                                  Context->getSizeType(), SourceLocation(),
3371                                  SourceLocation());
3372     // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
3373     // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases.
3374     // For X86 it is more complicated and some kind of target specific routine
3375     // is needed to decide what to do.
3376     unsigned IntSize =
3377       static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
3378     IntegerLiteral *limit = IntegerLiteral::Create(*Context,
3379                                                    llvm::APInt(IntSize, 8),
3380                                                    Context->IntTy,
3381                                                    SourceLocation());
3382     BinaryOperator *lessThanExpr = 
3383       new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy,
3384                                    VK_RValue, OK_Ordinary, SourceLocation());
3385     // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
3386     ConditionalOperator *CondExpr =
3387       new (Context) ConditionalOperator(lessThanExpr,
3388                                         SourceLocation(), CE,
3389                                         SourceLocation(), STCE,
3390                                         returnType, VK_RValue, OK_Ordinary);
3391     ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
3392                                             CondExpr);
3393   }
3394   // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
3395   return ReplacingStmt;
3396 }
3397
3398 Stmt *RewriteModernObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
3399   Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(),
3400                                          Exp->getLocEnd());
3401
3402   // Now do the actual rewrite.
3403   ReplaceStmt(Exp, ReplacingStmt);
3404
3405   // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
3406   return ReplacingStmt;
3407 }
3408
3409 // typedef struct objc_object Protocol;
3410 QualType RewriteModernObjC::getProtocolType() {
3411   if (!ProtocolTypeDecl) {
3412     TypeSourceInfo *TInfo
3413       = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
3414     ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
3415                                            SourceLocation(), SourceLocation(),
3416                                            &Context->Idents.get("Protocol"),
3417                                            TInfo);
3418   }
3419   return Context->getTypeDeclType(ProtocolTypeDecl);
3420 }
3421
3422 /// RewriteObjCProtocolExpr - Rewrite a protocol expression into
3423 /// a synthesized/forward data reference (to the protocol's metadata).
3424 /// The forward references (and metadata) are generated in
3425 /// RewriteModernObjC::HandleTranslationUnit().
3426 Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
3427   std::string Name = "_OBJC_PROTOCOL_REFERENCE_$_" + 
3428                       Exp->getProtocol()->getNameAsString();
3429   IdentifierInfo *ID = &Context->Idents.get(Name);
3430   VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
3431                                 SourceLocation(), ID, getProtocolType(), 0,
3432                                 SC_Extern, SC_None);
3433   DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
3434                                                VK_LValue, SourceLocation());
3435   Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
3436                              Context->getPointerType(DRE->getType()),
3437                              VK_RValue, OK_Ordinary, SourceLocation());
3438   CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(),
3439                                                 CK_BitCast,
3440                                                 DerefExpr);
3441   ReplaceStmt(Exp, castExpr);
3442   ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl());
3443   // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
3444   return castExpr;
3445
3446 }
3447
3448 bool RewriteModernObjC::BufferContainsPPDirectives(const char *startBuf,
3449                                              const char *endBuf) {
3450   while (startBuf < endBuf) {
3451     if (*startBuf == '#') {
3452       // Skip whitespace.
3453       for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf)
3454         ;
3455       if (!strncmp(startBuf, "if", strlen("if")) ||
3456           !strncmp(startBuf, "ifdef", strlen("ifdef")) ||
3457           !strncmp(startBuf, "ifndef", strlen("ifndef")) ||
3458           !strncmp(startBuf, "define", strlen("define")) ||
3459           !strncmp(startBuf, "undef", strlen("undef")) ||
3460           !strncmp(startBuf, "else", strlen("else")) ||
3461           !strncmp(startBuf, "elif", strlen("elif")) ||
3462           !strncmp(startBuf, "endif", strlen("endif")) ||
3463           !strncmp(startBuf, "pragma", strlen("pragma")) ||
3464           !strncmp(startBuf, "include", strlen("include")) ||
3465           !strncmp(startBuf, "import", strlen("import")) ||
3466           !strncmp(startBuf, "include_next", strlen("include_next")))
3467         return true;
3468     }
3469     startBuf++;
3470   }
3471   return false;
3472 }
3473
3474 /// RewriteObjCFieldDeclType - This routine rewrites a type into the buffer.
3475 /// It handles elaborated types, as well as enum types in the process.
3476 bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, 
3477                                                  std::string &Result) {
3478   if (Type->isArrayType()) {
3479     QualType ElemTy = Context->getBaseElementType(Type);
3480     return RewriteObjCFieldDeclType(ElemTy, Result);
3481   }
3482   else if (Type->isRecordType()) {
3483     RecordDecl *RD = Type->getAs<RecordType>()->getDecl();
3484     if (RD->isCompleteDefinition()) {
3485       if (RD->isStruct())
3486         Result += "\n\tstruct ";
3487       else if (RD->isUnion())
3488         Result += "\n\tunion ";
3489       else
3490         assert(false && "class not allowed as an ivar type");
3491       
3492       Result += RD->getName();
3493       if (TagsDefinedInIvarDecls.count(RD)) {
3494         // This struct is already defined. Do not write its definition again.
3495         Result += " ";
3496         return true;
3497       }
3498       TagsDefinedInIvarDecls.insert(RD);
3499       Result += " {\n";
3500       for (RecordDecl::field_iterator i = RD->field_begin(), 
3501            e = RD->field_end(); i != e; ++i) {
3502         FieldDecl *FD = *i;
3503         RewriteObjCFieldDecl(FD, Result);
3504       }
3505       Result += "\t} "; 
3506       return true;
3507     }
3508   }
3509   else if (Type->isEnumeralType()) {
3510     EnumDecl *ED = Type->getAs<EnumType>()->getDecl();
3511     if (ED->isCompleteDefinition()) {
3512       Result += "\n\tenum ";
3513       Result += ED->getName();
3514       if (TagsDefinedInIvarDecls.count(ED)) {
3515         // This enum is already defined. Do not write its definition again.
3516         Result += " ";
3517         return true;
3518       }
3519       TagsDefinedInIvarDecls.insert(ED);
3520       
3521       Result += " {\n";
3522       for (EnumDecl::enumerator_iterator EC = ED->enumerator_begin(),
3523            ECEnd = ED->enumerator_end(); EC != ECEnd; ++EC) {
3524         Result += "\t"; Result += EC->getName(); Result += " = ";
3525         llvm::APSInt Val = EC->getInitVal();
3526         Result += Val.toString(10);
3527         Result += ",\n";
3528       }
3529       Result += "\t} "; 
3530       return true;
3531     }
3532   }
3533   
3534   Result += "\t";
3535   convertObjCTypeToCStyleType(Type);
3536   return false;
3537 }
3538
3539
3540 /// RewriteObjCFieldDecl - This routine rewrites a field into the buffer.
3541 /// It handles elaborated types, as well as enum types in the process.
3542 void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl, 
3543                                              std::string &Result) {
3544   QualType Type = fieldDecl->getType();
3545   std::string Name = fieldDecl->getNameAsString();
3546   
3547   bool EleboratedType = RewriteObjCFieldDeclType(Type, Result); 
3548   if (!EleboratedType)
3549     Type.getAsStringInternal(Name, Context->getPrintingPolicy());
3550   Result += Name;
3551   if (fieldDecl->isBitField()) {
3552     Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context));
3553   }
3554   else if (EleboratedType && Type->isArrayType()) {
3555     CanQualType CType = Context->getCanonicalType(Type);
3556     while (isa<ArrayType>(CType)) {
3557       if (const ConstantArrayType *CAT = Context->getAsConstantArrayType(CType)) {
3558         Result += "[";
3559         llvm::APInt Dim = CAT->getSize();
3560         Result += utostr(Dim.getZExtValue());
3561         Result += "]";
3562       }
3563       CType = CType->getAs<ArrayType>()->getElementType();
3564     }
3565   }
3566   
3567   Result += ";\n";
3568 }
3569
3570 /// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to
3571 /// an objective-c class with ivars.
3572 void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
3573                                                std::string &Result) {
3574   assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
3575   assert(CDecl->getName() != "" &&
3576          "Name missing in SynthesizeObjCInternalStruct");
3577   ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
3578   SmallVector<ObjCIvarDecl *, 8> IVars;
3579   for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
3580        IVD; IVD = IVD->getNextIvar())
3581     IVars.push_back(IVD);
3582   
3583   SourceLocation LocStart = CDecl->getLocStart();
3584   SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc();
3585   
3586   const char *startBuf = SM->getCharacterData(LocStart);
3587   const char *endBuf = SM->getCharacterData(LocEnd);
3588   
3589   // If no ivars and no root or if its root, directly or indirectly,
3590   // have no ivars (thus not synthesized) then no need to synthesize this class.
3591   if ((!CDecl->isThisDeclarationADefinition() || IVars.size() == 0) &&
3592       (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3593     endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
3594     ReplaceText(LocStart, endBuf-startBuf, Result);
3595     return;
3596   }
3597   
3598   Result += "\nstruct ";
3599   Result += CDecl->getNameAsString();
3600   Result += "_IMPL {\n";
3601   
3602   if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3603     Result += "\tstruct "; Result += RCDecl->getNameAsString();
3604     Result += "_IMPL "; Result += RCDecl->getNameAsString();
3605     Result += "_IVARS;\n";
3606   }
3607   TagsDefinedInIvarDecls.clear();
3608   for (unsigned i = 0, e = IVars.size(); i < e; i++)
3609     RewriteObjCFieldDecl(IVars[i], Result);
3610
3611   Result += "};\n";
3612   endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
3613   ReplaceText(LocStart, endBuf-startBuf, Result);
3614   // Mark this struct as having been generated.
3615   if (!ObjCSynthesizedStructs.insert(CDecl))
3616     llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct");
3617 }
3618
3619 static void WriteInternalIvarName(ObjCInterfaceDecl *IDecl,
3620                                   ObjCIvarDecl *IvarDecl, std::string &Result) {
3621   Result += "OBJC_IVAR_$_";
3622   Result += IDecl->getName();
3623   Result += "$";
3624   Result += IvarDecl->getName();
3625 }
3626
3627 /// RewriteIvarOffsetSymbols - Rewrite ivar offset symbols of those ivars which
3628 /// have been referenced in an ivar access expression.
3629 void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
3630                                                   std::string &Result) {
3631   // write out ivar offset symbols which have been referenced in an ivar
3632   // access expression.
3633   llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];
3634   if (Ivars.empty())
3635     return;
3636   for (llvm::SmallPtrSet<ObjCIvarDecl *, 8>::iterator i = Ivars.begin(),
3637        e = Ivars.end(); i != e; i++) {
3638     ObjCIvarDecl *IvarDecl = (*i);
3639     Result += "\n";
3640     if (LangOpts.MicrosoftExt)
3641       Result += "__declspec(allocate(\".objc_ivar$B\")) ";
3642     Result += "extern \"C\" ";
3643     if (LangOpts.MicrosoftExt && 
3644         IvarDecl->getAccessControl() != ObjCIvarDecl::Private &&
3645         IvarDecl->getAccessControl() != ObjCIvarDecl::Package)
3646         Result += "__declspec(dllimport) ";
3647
3648     Result += "unsigned long ";
3649     WriteInternalIvarName(CDecl, IvarDecl, Result);
3650     Result += ";";
3651   }
3652 }
3653
3654 //===----------------------------------------------------------------------===//
3655 // Meta Data Emission
3656 //===----------------------------------------------------------------------===//
3657
3658
3659 /// RewriteImplementations - This routine rewrites all method implementations
3660 /// and emits meta-data.
3661
3662 void RewriteModernObjC::RewriteImplementations() {
3663   int ClsDefCount = ClassImplementation.size();
3664   int CatDefCount = CategoryImplementation.size();
3665
3666   // Rewrite implemented methods
3667   for (int i = 0; i < ClsDefCount; i++) {
3668     ObjCImplementationDecl *OIMP = ClassImplementation[i];
3669     ObjCInterfaceDecl *CDecl = OIMP->getClassInterface();
3670     if (CDecl->isImplicitInterfaceDecl())
3671       assert(false &&
3672              "Legacy implicit interface rewriting not supported in moder abi");
3673     RewriteImplementationDecl(OIMP);
3674   }
3675
3676   for (int i = 0; i < CatDefCount; i++) {
3677     ObjCCategoryImplDecl *CIMP = CategoryImplementation[i];
3678     ObjCInterfaceDecl *CDecl = CIMP->getClassInterface();
3679     if (CDecl->isImplicitInterfaceDecl())
3680       assert(false &&
3681              "Legacy implicit interface rewriting not supported in moder abi");
3682     RewriteImplementationDecl(CIMP);
3683   }
3684 }
3685
3686 void RewriteModernObjC::RewriteByRefString(std::string &ResultStr, 
3687                                      const std::string &Name,
3688                                      ValueDecl *VD, bool def) {
3689   assert(BlockByRefDeclNo.count(VD) && 
3690          "RewriteByRefString: ByRef decl missing");
3691   if (def)
3692     ResultStr += "struct ";
3693   ResultStr += "__Block_byref_" + Name + 
3694     "_" + utostr(BlockByRefDeclNo[VD]) ;
3695 }
3696
3697 static bool HasLocalVariableExternalStorage(ValueDecl *VD) {
3698   if (VarDecl *Var = dyn_cast<VarDecl>(VD))
3699     return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
3700   return false;
3701 }
3702
3703 std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
3704                                                    StringRef funcName,
3705                                                    std::string Tag) {
3706   const FunctionType *AFT = CE->getFunctionType();
3707   QualType RT = AFT->getResultType();
3708   std::string StructRef = "struct " + Tag;
3709   std::string S = "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" +
3710                   funcName.str() + "_block_func_" + utostr(i);
3711
3712   BlockDecl *BD = CE->getBlockDecl();
3713
3714   if (isa<FunctionNoProtoType>(AFT)) {
3715     // No user-supplied arguments. Still need to pass in a pointer to the
3716     // block (to reference imported block decl refs).
3717     S += "(" + StructRef + " *__cself)";
3718   } else if (BD->param_empty()) {
3719     S += "(" + StructRef + " *__cself)";
3720   } else {
3721     const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
3722     assert(FT && "SynthesizeBlockFunc: No function proto");
3723     S += '(';
3724     // first add the implicit argument.
3725     S += StructRef + " *__cself, ";
3726     std::string ParamStr;
3727     for (BlockDecl::param_iterator AI = BD->param_begin(),
3728          E = BD->param_end(); AI != E; ++AI) {
3729       if (AI != BD->param_begin()) S += ", ";
3730       ParamStr = (*AI)->getNameAsString();
3731       QualType QT = (*AI)->getType();
3732       (void)convertBlockPointerToFunctionPointer(QT);
3733       QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy());
3734       S += ParamStr;
3735     }
3736     if (FT->isVariadic()) {
3737       if (!BD->param_empty()) S += ", ";
3738       S += "...";
3739     }
3740     S += ')';
3741   }
3742   S += " {\n";
3743
3744   // Create local declarations to avoid rewriting all closure decl ref exprs.
3745   // First, emit a declaration for all "by ref" decls.
3746   for (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
3747        E = BlockByRefDecls.end(); I != E; ++I) {
3748     S += "  ";
3749     std::string Name = (*I)->getNameAsString();
3750     std::string TypeString;
3751     RewriteByRefString(TypeString, Name, (*I));
3752     TypeString += " *";
3753     Name = TypeString + Name;
3754     S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
3755   }
3756   // Next, emit a declaration for all "by copy" declarations.
3757   for (SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
3758        E = BlockByCopyDecls.end(); I != E; ++I) {
3759     S += "  ";
3760     // Handle nested closure invocation. For example:
3761     //
3762     //   void (^myImportedClosure)(void);
3763     //   myImportedClosure  = ^(void) { setGlobalInt(x + y); };
3764     //
3765     //   void (^anotherClosure)(void);
3766     //   anotherClosure = ^(void) {
3767     //     myImportedClosure(); // import and invoke the closure
3768     //   };
3769     //
3770     if (isTopLevelBlockPointerType((*I)->getType())) {
3771       RewriteBlockPointerTypeVariable(S, (*I));
3772       S += " = (";
3773       RewriteBlockPointerType(S, (*I)->getType());
3774       S += ")";
3775       S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
3776     }
3777     else {
3778       std::string Name = (*I)->getNameAsString();
3779       QualType QT = (*I)->getType();
3780       if (HasLocalVariableExternalStorage(*I))
3781         QT = Context->getPointerType(QT);
3782       QT.getAsStringInternal(Name, Context->getPrintingPolicy());
3783       S += Name + " = __cself->" + 
3784                               (*I)->getNameAsString() + "; // bound by copy\n";
3785     }
3786   }
3787   std::string RewrittenStr = RewrittenBlockExprs[CE];
3788   const char *cstr = RewrittenStr.c_str();
3789   while (*cstr++ != '{') ;
3790   S += cstr;
3791   S += "\n";
3792   return S;
3793 }
3794
3795 std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
3796                                                    StringRef funcName,
3797                                                    std::string Tag) {
3798   std::string StructRef = "struct " + Tag;
3799   std::string S = "static void __";
3800
3801   S += funcName;
3802   S += "_block_copy_" + utostr(i);
3803   S += "(" + StructRef;
3804   S += "*dst, " + StructRef;
3805   S += "*src) {";
3806   for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
3807       E = ImportedBlockDecls.end(); I != E; ++I) {
3808     ValueDecl *VD = (*I);
3809     S += "_Block_object_assign((void*)&dst->";
3810     S += (*I)->getNameAsString();
3811     S += ", (void*)src->";
3812     S += (*I)->getNameAsString();
3813     if (BlockByRefDeclsPtrSet.count((*I)))
3814       S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
3815     else if (VD->getType()->isBlockPointerType())
3816       S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
3817     else
3818       S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
3819   }
3820   S += "}\n";
3821   
3822   S += "\nstatic void __";
3823   S += funcName;
3824   S += "_block_dispose_" + utostr(i);
3825   S += "(" + StructRef;
3826   S += "*src) {";
3827   for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
3828       E = ImportedBlockDecls.end(); I != E; ++I) {
3829     ValueDecl *VD = (*I);
3830     S += "_Block_object_dispose((void*)src->";
3831     S += (*I)->getNameAsString();
3832     if (BlockByRefDeclsPtrSet.count((*I)))
3833       S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
3834     else if (VD->getType()->isBlockPointerType())
3835       S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
3836     else
3837       S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
3838   }
3839   S += "}\n";
3840   return S;
3841 }
3842
3843 std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
3844                                              std::string Desc) {
3845   std::string S = "\nstruct " + Tag;
3846   std::string Constructor = "  " + Tag;
3847
3848   S += " {\n  struct __block_impl impl;\n";
3849   S += "  struct " + Desc;
3850   S += "* Desc;\n";
3851
3852   Constructor += "(void *fp, "; // Invoke function pointer.
3853   Constructor += "struct " + Desc; // Descriptor pointer.
3854   Constructor += " *desc";
3855
3856   if (BlockDeclRefs.size()) {
3857     // Output all "by copy" declarations.
3858     for (SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
3859          E = BlockByCopyDecls.end(); I != E; ++I) {
3860       S += "  ";
3861       std::string FieldName = (*I)->getNameAsString();
3862       std::string ArgName = "_" + FieldName;
3863       // Handle nested closure invocation. For example:
3864       //
3865       //   void (^myImportedBlock)(void);
3866       //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
3867       //
3868       //   void (^anotherBlock)(void);
3869       //   anotherBlock = ^(void) {
3870       //     myImportedBlock(); // import and invoke the closure
3871       //   };
3872       //
3873       if (isTopLevelBlockPointerType((*I)->getType())) {
3874         S += "struct __block_impl *";
3875         Constructor += ", void *" + ArgName;
3876       } else {
3877         QualType QT = (*I)->getType();
3878         if (HasLocalVariableExternalStorage(*I))
3879           QT = Context->getPointerType(QT);
3880         QT.getAsStringInternal(FieldName, Context->getPrintingPolicy());
3881         QT.getAsStringInternal(ArgName, Context->getPrintingPolicy());
3882         Constructor += ", " + ArgName;
3883       }
3884       S += FieldName + ";\n";
3885     }
3886     // Output all "by ref" declarations.
3887     for (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
3888          E = BlockByRefDecls.end(); I != E; ++I) {
3889       S += "  ";
3890       std::string FieldName = (*I)->getNameAsString();
3891       std::string ArgName = "_" + FieldName;
3892       {
3893         std::string TypeString;
3894         RewriteByRefString(TypeString, FieldName, (*I));
3895         TypeString += " *";
3896         FieldName = TypeString + FieldName;
3897         ArgName = TypeString + ArgName;
3898         Constructor += ", " + ArgName;
3899       }
3900       S += FieldName + "; // by ref\n";
3901     }
3902     // Finish writing the constructor.
3903     Constructor += ", int flags=0)";
3904     // Initialize all "by copy" arguments.
3905     bool firsTime = true;
3906     for (SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
3907          E = BlockByCopyDecls.end(); I != E; ++I) {
3908       std::string Name = (*I)->getNameAsString();
3909         if (firsTime) {
3910           Constructor += " : ";
3911           firsTime = false;
3912         }
3913         else
3914           Constructor += ", ";
3915         if (isTopLevelBlockPointerType((*I)->getType()))
3916           Constructor += Name + "((struct __block_impl *)_" + Name + ")";
3917         else
3918           Constructor += Name + "(_" + Name + ")";
3919     }
3920     // Initialize all "by ref" arguments.
3921     for (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
3922          E = BlockByRefDecls.end(); I != E; ++I) {
3923       std::string Name = (*I)->getNameAsString();
3924       if (firsTime) {
3925         Constructor += " : ";
3926         firsTime = false;
3927       }
3928       else
3929         Constructor += ", ";
3930       Constructor += Name + "(_" + Name + "->__forwarding)";
3931     }
3932     
3933     Constructor += " {\n";
3934     if (GlobalVarDecl)
3935       Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
3936     else
3937       Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
3938     Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
3939
3940     Constructor += "    Desc = desc;\n";
3941   } else {
3942     // Finish writing the constructor.
3943     Constructor += ", int flags=0) {\n";
3944     if (GlobalVarDecl)
3945       Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
3946     else
3947       Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
3948     Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
3949     Constructor += "    Desc = desc;\n";
3950   }
3951   Constructor += "  ";
3952   Constructor += "}\n";
3953   S += Constructor;
3954   S += "};\n";
3955   return S;
3956 }
3957
3958 std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag, 
3959                                                    std::string ImplTag, int i,
3960                                                    StringRef FunName,
3961                                                    unsigned hasCopy) {
3962   std::string S = "\nstatic struct " + DescTag;
3963   
3964   S += " {\n  unsigned long reserved;\n";
3965   S += "  unsigned long Block_size;\n";
3966   if (hasCopy) {
3967     S += "  void (*copy)(struct ";
3968     S += ImplTag; S += "*, struct ";
3969     S += ImplTag; S += "*);\n";
3970     
3971     S += "  void (*dispose)(struct ";
3972     S += ImplTag; S += "*);\n";
3973   }
3974   S += "} ";
3975
3976   S += DescTag + "_DATA = { 0, sizeof(struct ";
3977   S += ImplTag + ")";
3978   if (hasCopy) {
3979     S += ", __" + FunName.str() + "_block_copy_" + utostr(i);
3980     S += ", __" + FunName.str() + "_block_dispose_" + utostr(i);
3981   }
3982   S += "};\n";
3983   return S;
3984 }
3985
3986 /// getFunctionSourceLocation - returns start location of a function
3987 /// definition. Complication arises when function has declared as
3988 /// extern "C" or extern "C" {...}
3989 static SourceLocation getFunctionSourceLocation (FunctionDecl *FD) {
3990   if (!FD->isExternC() || FD->isMain())
3991     return FD->getTypeSpecStartLoc();
3992   const DeclContext *DC = FD->getDeclContext();
3993   if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
3994     SourceLocation BodyRBrace = LSD->getRBraceLoc();
3995     // if it is extern "C" {...}, return function decl's own location.
3996     if (BodyRBrace.isValid())
3997       return FD->getTypeSpecStartLoc();
3998     return LSD->getExternLoc();
3999   }
4000   return FD->getTypeSpecStartLoc();
4001 }
4002
4003 void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
4004                                           StringRef FunName) {
4005   bool RewriteSC = (GlobalVarDecl &&
4006                     !Blocks.empty() &&
4007                     GlobalVarDecl->getStorageClass() == SC_Static &&
4008                     GlobalVarDecl->getType().getCVRQualifiers());
4009   if (RewriteSC) {
4010     std::string SC(" void __");
4011     SC += GlobalVarDecl->getNameAsString();
4012     SC += "() {}";
4013     InsertText(FunLocStart, SC);
4014   }
4015   
4016   // Insert closures that were part of the function.
4017   for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
4018     CollectBlockDeclRefInfo(Blocks[i]);
4019     // Need to copy-in the inner copied-in variables not actually used in this
4020     // block.
4021     for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
4022       DeclRefExpr *Exp = InnerDeclRefs[count++];
4023       ValueDecl *VD = Exp->getDecl();
4024       BlockDeclRefs.push_back(Exp);
4025       if (!VD->hasAttr<BlocksAttr>()) {
4026         if (!BlockByCopyDeclsPtrSet.count(VD)) {
4027           BlockByCopyDeclsPtrSet.insert(VD);
4028           BlockByCopyDecls.push_back(VD);
4029         }
4030         continue;
4031       }
4032
4033       if (!BlockByRefDeclsPtrSet.count(VD)) {
4034         BlockByRefDeclsPtrSet.insert(VD);
4035         BlockByRefDecls.push_back(VD);
4036       }
4037
4038       // imported objects in the inner blocks not used in the outer
4039       // blocks must be copied/disposed in the outer block as well.
4040       if (VD->getType()->isObjCObjectPointerType() || 
4041           VD->getType()->isBlockPointerType())
4042         ImportedBlockDecls.insert(VD);
4043     }
4044
4045     std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i);
4046     std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i);
4047
4048     std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4049
4050     InsertText(FunLocStart, CI);
4051
4052     std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4053
4054     InsertText(FunLocStart, CF);
4055
4056     if (ImportedBlockDecls.size()) {
4057       std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4058       InsertText(FunLocStart, HF);
4059     }
4060     std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4061                                                ImportedBlockDecls.size() > 0);
4062     InsertText(FunLocStart, BD);
4063
4064     BlockDeclRefs.clear();
4065     BlockByRefDecls.clear();
4066     BlockByRefDeclsPtrSet.clear();
4067     BlockByCopyDecls.clear();
4068     BlockByCopyDeclsPtrSet.clear();
4069     ImportedBlockDecls.clear();
4070   }
4071   if (RewriteSC) {
4072     // Must insert any 'const/volatile/static here. Since it has been
4073     // removed as result of rewriting of block literals.
4074     std::string SC;
4075     if (GlobalVarDecl->getStorageClass() == SC_Static)
4076       SC = "static ";
4077     if (GlobalVarDecl->getType().isConstQualified())
4078       SC += "const ";
4079     if (GlobalVarDecl->getType().isVolatileQualified())
4080       SC += "volatile ";
4081     if (GlobalVarDecl->getType().isRestrictQualified())
4082       SC += "restrict ";
4083     InsertText(FunLocStart, SC);
4084   }
4085   if (GlobalConstructionExp) {
4086     // extra fancy dance for global literal expression.
4087     
4088     // Always the latest block expression on the block stack.
4089     std::string Tag = "__";
4090     Tag += FunName;
4091     Tag += "_block_impl_";
4092     Tag += utostr(Blocks.size()-1);
4093     std::string globalBuf = "static ";
4094     globalBuf += Tag; globalBuf += " ";
4095     std::string SStr;
4096   
4097     llvm::raw_string_ostream constructorExprBuf(SStr);
4098     GlobalConstructionExp->printPretty(constructorExprBuf, *Context, 0,
4099                                          PrintingPolicy(LangOpts));
4100     globalBuf += constructorExprBuf.str();
4101     globalBuf += ";\n";
4102     InsertText(FunLocStart, globalBuf);
4103     GlobalConstructionExp = 0;
4104   }
4105
4106   Blocks.clear();
4107   InnerDeclRefsCount.clear();
4108   InnerDeclRefs.clear();
4109   RewrittenBlockExprs.clear();
4110 }
4111
4112 void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
4113   SourceLocation FunLocStart = getFunctionSourceLocation(FD);
4114   StringRef FuncName = FD->getName();
4115
4116   SynthesizeBlockLiterals(FunLocStart, FuncName);
4117 }
4118
4119 static void BuildUniqueMethodName(std::string &Name,
4120                                   ObjCMethodDecl *MD) {
4121   ObjCInterfaceDecl *IFace = MD->getClassInterface();
4122   Name = IFace->getName();
4123   Name += "__" + MD->getSelector().getAsString();
4124   // Convert colons to underscores.
4125   std::string::size_type loc = 0;
4126   while ((loc = Name.find(":", loc)) != std::string::npos)
4127     Name.replace(loc, 1, "_");
4128 }
4129
4130 void RewriteModernObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
4131   //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
4132   //SourceLocation FunLocStart = MD->getLocStart();
4133   SourceLocation FunLocStart = MD->getLocStart();
4134   std::string FuncName;
4135   BuildUniqueMethodName(FuncName, MD);
4136   SynthesizeBlockLiterals(FunLocStart, FuncName);
4137 }
4138
4139 void RewriteModernObjC::GetBlockDeclRefExprs(Stmt *S) {
4140   for (Stmt::child_range CI = S->children(); CI; ++CI)
4141     if (*CI) {
4142       if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
4143         GetBlockDeclRefExprs(CBE->getBody());
4144       else
4145         GetBlockDeclRefExprs(*CI);
4146     }
4147   // Handle specific things.
4148   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4149     if (DRE->refersToEnclosingLocal()) {
4150       // FIXME: Handle enums.
4151       if (!isa<FunctionDecl>(DRE->getDecl()))
4152         BlockDeclRefs.push_back(DRE);
4153       if (HasLocalVariableExternalStorage(DRE->getDecl()))
4154         BlockDeclRefs.push_back(DRE);
4155     }
4156   }
4157   
4158   return;
4159 }
4160
4161 void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S, 
4162                 SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs,
4163                 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
4164   for (Stmt::child_range CI = S->children(); CI; ++CI)
4165     if (*CI) {
4166       if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
4167         InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4168         GetInnerBlockDeclRefExprs(CBE->getBody(),
4169                                   InnerBlockDeclRefs,
4170                                   InnerContexts);
4171       }
4172       else
4173         GetInnerBlockDeclRefExprs(*CI,
4174                                   InnerBlockDeclRefs,
4175                                   InnerContexts);
4176
4177     }
4178   // Handle specific things.
4179   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4180     if (DRE->refersToEnclosingLocal()) {
4181       if (!isa<FunctionDecl>(DRE->getDecl()) &&
4182           !InnerContexts.count(DRE->getDecl()->getDeclContext()))
4183         InnerBlockDeclRefs.push_back(DRE);
4184       if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
4185         if (Var->isFunctionOrMethodVarDecl())
4186           ImportedLocalExternalDecls.insert(Var);
4187     }
4188   }
4189   
4190   return;
4191 }
4192
4193 /// convertObjCTypeToCStyleType - This routine converts such objc types
4194 /// as qualified objects, and blocks to their closest c/c++ types that
4195 /// it can. It returns true if input type was modified.
4196 bool RewriteModernObjC::convertObjCTypeToCStyleType(QualType &T) {
4197   QualType oldT = T;
4198   convertBlockPointerToFunctionPointer(T);
4199   if (T->isFunctionPointerType()) {
4200     QualType PointeeTy;
4201     if (const PointerType* PT = T->getAs<PointerType>()) {
4202       PointeeTy = PT->getPointeeType();
4203       if (const FunctionType *FT = PointeeTy->getAs<FunctionType>()) {
4204         T = convertFunctionTypeOfBlocks(FT);
4205         T = Context->getPointerType(T);
4206       }
4207     }
4208   }
4209   
4210   convertToUnqualifiedObjCType(T);
4211   return T != oldT;
4212 }
4213
4214 /// convertFunctionTypeOfBlocks - This routine converts a function type
4215 /// whose result type may be a block pointer or whose argument type(s)
4216 /// might be block pointers to an equivalent function type replacing
4217 /// all block pointers to function pointers.
4218 QualType RewriteModernObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {
4219   const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
4220   // FTP will be null for closures that don't take arguments.
4221   // Generate a funky cast.
4222   SmallVector<QualType, 8> ArgTypes;
4223   QualType Res = FT->getResultType();
4224   bool modified = convertObjCTypeToCStyleType(Res);
4225   
4226   if (FTP) {
4227     for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
4228          E = FTP->arg_type_end(); I && (I != E); ++I) {
4229       QualType t = *I;
4230       // Make sure we convert "t (^)(...)" to "t (*)(...)".
4231       if (convertObjCTypeToCStyleType(t))
4232         modified = true;
4233       ArgTypes.push_back(t);
4234     }
4235   }
4236   QualType FuncType;
4237   if (modified)
4238     FuncType = getSimpleFunctionType(Res, &ArgTypes[0], ArgTypes.size());
4239   else FuncType = QualType(FT, 0);
4240   return FuncType;
4241 }
4242
4243 Stmt *RewriteModernObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
4244   // Navigate to relevant type information.
4245   const BlockPointerType *CPT = 0;
4246
4247   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4248     CPT = DRE->getType()->getAs<BlockPointerType>();
4249   } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4250     CPT = MExpr->getType()->getAs<BlockPointerType>();
4251   } 
4252   else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4253     return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4254   }
4255   else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 
4256     CPT = IEXPR->getType()->getAs<BlockPointerType>();
4257   else if (const ConditionalOperator *CEXPR = 
4258             dyn_cast<ConditionalOperator>(BlockExp)) {
4259     Expr *LHSExp = CEXPR->getLHS();
4260     Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4261     Expr *RHSExp = CEXPR->getRHS();
4262     Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4263     Expr *CONDExp = CEXPR->getCond();
4264     ConditionalOperator *CondExpr =
4265       new (Context) ConditionalOperator(CONDExp,
4266                                       SourceLocation(), cast<Expr>(LHSStmt),
4267                                       SourceLocation(), cast<Expr>(RHSStmt),
4268                                       Exp->getType(), VK_RValue, OK_Ordinary);
4269     return CondExpr;
4270   } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4271     CPT = IRE->getType()->getAs<BlockPointerType>();
4272   } else if (const PseudoObjectExpr *POE
4273                = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4274     CPT = POE->getType()->castAs<BlockPointerType>();
4275   } else {
4276     assert(1 && "RewriteBlockClass: Bad type");
4277   }
4278   assert(CPT && "RewriteBlockClass: Bad type");
4279   const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>();
4280   assert(FT && "RewriteBlockClass: Bad type");
4281   const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
4282   // FTP will be null for closures that don't take arguments.
4283
4284   RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
4285                                       SourceLocation(), SourceLocation(),
4286                                       &Context->Idents.get("__block_impl"));
4287   QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
4288
4289   // Generate a funky cast.
4290   SmallVector<QualType, 8> ArgTypes;
4291
4292   // Push the block argument type.
4293   ArgTypes.push_back(PtrBlock);
4294   if (FTP) {
4295     for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
4296          E = FTP->arg_type_end(); I && (I != E); ++I) {
4297       QualType t = *I;
4298       // Make sure we convert "t (^)(...)" to "t (*)(...)".
4299       if (!convertBlockPointerToFunctionPointer(t))
4300         convertToUnqualifiedObjCType(t);
4301       ArgTypes.push_back(t);
4302     }
4303   }
4304   // Now do the pointer to function cast.
4305   QualType PtrToFuncCastType
4306     = getSimpleFunctionType(Exp->getType(), &ArgTypes[0], ArgTypes.size());
4307
4308   PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
4309
4310   CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4311                                                CK_BitCast,
4312                                                const_cast<Expr*>(BlockExp));
4313   // Don't forget the parens to enforce the proper binding.
4314   ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
4315                                           BlkCast);
4316   //PE->dump();
4317
4318   FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
4319                                     SourceLocation(),
4320                                     &Context->Idents.get("FuncPtr"),
4321                                     Context->VoidPtrTy, 0,
4322                                     /*BitWidth=*/0, /*Mutable=*/true,
4323                                     /*HasInit=*/false);
4324   MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
4325                                             FD->getType(), VK_LValue,
4326                                             OK_Ordinary);
4327
4328   
4329   CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4330                                                 CK_BitCast, ME);
4331   PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast);
4332
4333   SmallVector<Expr*, 8> BlkExprs;
4334   // Add the implicit argument.
4335   BlkExprs.push_back(BlkCast);
4336   // Add the user arguments.
4337   for (CallExpr::arg_iterator I = Exp->arg_begin(),
4338        E = Exp->arg_end(); I != E; ++I) {
4339     BlkExprs.push_back(*I);
4340   }
4341   CallExpr *CE = new (Context) CallExpr(*Context, PE, &BlkExprs[0],
4342                                         BlkExprs.size(),
4343                                         Exp->getType(), VK_RValue,
4344                                         SourceLocation());
4345   return CE;
4346 }
4347
4348 // We need to return the rewritten expression to handle cases where the
4349 // DeclRefExpr is embedded in another expression being rewritten.
4350 // For example:
4351 //
4352 // int main() {
4353 //    __block Foo *f;
4354 //    __block int i;
4355 //
4356 //    void (^myblock)() = ^() {
4357 //        [f test]; // f is a DeclRefExpr embedded in a message (which is being rewritten).
4358 //        i = 77;
4359 //    };
4360 //}
4361 Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {
4362   // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
4363   // for each DeclRefExp where BYREFVAR is name of the variable.
4364   ValueDecl *VD = DeclRefExp->getDecl();
4365   bool isArrow = DeclRefExp->refersToEnclosingLocal();
4366   
4367   FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
4368                                     SourceLocation(),
4369                                     &Context->Idents.get("__forwarding"), 
4370                                     Context->VoidPtrTy, 0,
4371                                     /*BitWidth=*/0, /*Mutable=*/true,
4372                                     /*HasInit=*/false);
4373   MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
4374                                             FD, SourceLocation(),
4375                                             FD->getType(), VK_LValue,
4376                                             OK_Ordinary);
4377
4378   StringRef Name = VD->getName();
4379   FD = FieldDecl::Create(*Context, 0, SourceLocation(), SourceLocation(),
4380                          &Context->Idents.get(Name), 
4381                          Context->VoidPtrTy, 0,
4382                          /*BitWidth=*/0, /*Mutable=*/true,
4383                          /*HasInit=*/false);
4384   ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
4385                                 DeclRefExp->getType(), VK_LValue, OK_Ordinary);
4386   
4387   
4388   
4389   // Need parens to enforce precedence.
4390   ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 
4391                                           DeclRefExp->getExprLoc(), 
4392                                           ME);
4393   ReplaceStmt(DeclRefExp, PE);
4394   return PE;
4395 }
4396
4397 // Rewrites the imported local variable V with external storage 
4398 // (static, extern, etc.) as *V
4399 //
4400 Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
4401   ValueDecl *VD = DRE->getDecl();
4402   if (VarDecl *Var = dyn_cast<VarDecl>(VD))
4403     if (!ImportedLocalExternalDecls.count(Var))
4404       return DRE;
4405   Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(),
4406                                           VK_LValue, OK_Ordinary,
4407                                           DRE->getLocation());
4408   // Need parens to enforce precedence.
4409   ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
4410                                           Exp);
4411   ReplaceStmt(DRE, PE);
4412   return PE;
4413 }
4414
4415 void RewriteModernObjC::RewriteCastExpr(CStyleCastExpr *CE) {
4416   SourceLocation LocStart = CE->getLParenLoc();
4417   SourceLocation LocEnd = CE->getRParenLoc();
4418
4419   // Need to avoid trying to rewrite synthesized casts.
4420   if (LocStart.isInvalid())
4421     return;
4422   // Need to avoid trying to rewrite casts contained in macros.
4423   if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4424     return;
4425
4426   const char *startBuf = SM->getCharacterData(LocStart);
4427   const char *endBuf = SM->getCharacterData(LocEnd);
4428   QualType QT = CE->getType();
4429   const Type* TypePtr = QT->getAs<Type>();
4430   if (isa<TypeOfExprType>(TypePtr)) {
4431     const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4432     QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
4433     std::string TypeAsString = "(";
4434     RewriteBlockPointerType(TypeAsString, QT);
4435     TypeAsString += ")";
4436     ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4437     return;
4438   }
4439   // advance the location to startArgList.
4440   const char *argPtr = startBuf;
4441
4442   while (*argPtr++ && (argPtr < endBuf)) {
4443     switch (*argPtr) {
4444     case '^':
4445       // Replace the '^' with '*'.
4446       LocStart = LocStart.getLocWithOffset(argPtr-startBuf);
4447       ReplaceText(LocStart, 1, "*");
4448       break;
4449     }
4450   }
4451   return;
4452 }
4453
4454 void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) {
4455   CastKind CastKind = IC->getCastKind();
4456   if (CastKind != CK_BlockPointerToObjCPointerCast &&
4457       CastKind != CK_AnyPointerToBlockPointerCast)
4458     return;
4459   
4460   QualType QT = IC->getType();
4461   (void)convertBlockPointerToFunctionPointer(QT);
4462   std::string TypeString(QT.getAsString(Context->getPrintingPolicy()));
4463   std::string Str = "(";
4464   Str += TypeString;
4465   Str += ")";
4466   InsertText(IC->getSubExpr()->getLocStart(), &Str[0], Str.size());
4467
4468   return;
4469 }
4470
4471 void RewriteModernObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
4472   SourceLocation DeclLoc = FD->getLocation();
4473   unsigned parenCount = 0;
4474
4475   // We have 1 or more arguments that have closure pointers.
4476   const char *startBuf = SM->getCharacterData(DeclLoc);
4477   const char *startArgList = strchr(startBuf, '(');
4478
4479   assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
4480
4481   parenCount++;
4482   // advance the location to startArgList.
4483   DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf);
4484   assert((DeclLoc.isValid()) && "Invalid DeclLoc");
4485
4486   const char *argPtr = startArgList;
4487
4488   while (*argPtr++ && parenCount) {
4489     switch (*argPtr) {
4490     case '^':
4491       // Replace the '^' with '*'.
4492       DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList);
4493       ReplaceText(DeclLoc, 1, "*");
4494       break;
4495     case '(':
4496       parenCount++;
4497       break;
4498     case ')':
4499       parenCount--;
4500       break;
4501     }
4502   }
4503   return;
4504 }
4505
4506 bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
4507   const FunctionProtoType *FTP;
4508   const PointerType *PT = QT->getAs<PointerType>();
4509   if (PT) {
4510     FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
4511   } else {
4512     const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
4513     assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4514     FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
4515   }
4516   if (FTP) {
4517     for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
4518          E = FTP->arg_type_end(); I != E; ++I)
4519       if (isTopLevelBlockPointerType(*I))
4520         return true;
4521   }
4522   return false;
4523 }
4524
4525 bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) {
4526   const FunctionProtoType *FTP;
4527   const PointerType *PT = QT->getAs<PointerType>();
4528   if (PT) {
4529     FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
4530   } else {
4531     const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
4532     assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4533     FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
4534   }
4535   if (FTP) {
4536     for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
4537          E = FTP->arg_type_end(); I != E; ++I) {
4538       if ((*I)->isObjCQualifiedIdType())
4539         return true;
4540       if ((*I)->isObjCObjectPointerType() &&
4541           (*I)->getPointeeType()->isObjCQualifiedInterfaceType())
4542         return true;
4543     }
4544         
4545   }
4546   return false;
4547 }
4548
4549 void RewriteModernObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
4550                                      const char *&RParen) {
4551   const char *argPtr = strchr(Name, '(');
4552   assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
4553
4554   LParen = argPtr; // output the start.
4555   argPtr++; // skip past the left paren.
4556   unsigned parenCount = 1;
4557
4558   while (*argPtr && parenCount) {
4559     switch (*argPtr) {
4560     case '(': parenCount++; break;
4561     case ')': parenCount--; break;
4562     default: break;
4563     }
4564     if (parenCount) argPtr++;
4565   }
4566   assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
4567   RParen = argPtr; // output the end
4568 }
4569
4570 void RewriteModernObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
4571   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
4572     RewriteBlockPointerFunctionArgs(FD);
4573     return;
4574   }
4575   // Handle Variables and Typedefs.
4576   SourceLocation DeclLoc = ND->getLocation();
4577   QualType DeclT;
4578   if (VarDecl *VD = dyn_cast<VarDecl>(ND))
4579     DeclT = VD->getType();
4580   else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND))
4581     DeclT = TDD->getUnderlyingType();
4582   else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4583     DeclT = FD->getType();
4584   else
4585     llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled");
4586
4587   const char *startBuf = SM->getCharacterData(DeclLoc);
4588   const char *endBuf = startBuf;
4589   // scan backward (from the decl location) for the end of the previous decl.
4590   while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
4591     startBuf--;
4592   SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf);
4593   std::string buf;
4594   unsigned OrigLength=0;
4595   // *startBuf != '^' if we are dealing with a pointer to function that
4596   // may take block argument types (which will be handled below).
4597   if (*startBuf == '^') {
4598     // Replace the '^' with '*', computing a negative offset.
4599     buf = '*';
4600     startBuf++;
4601     OrigLength++;
4602   }
4603   while (*startBuf != ')') {
4604     buf += *startBuf;
4605     startBuf++;
4606     OrigLength++;
4607   }
4608   buf += ')';
4609   OrigLength++;
4610   
4611   if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4612       PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4613     // Replace the '^' with '*' for arguments.
4614     // Replace id<P> with id/*<>*/
4615     DeclLoc = ND->getLocation();
4616     startBuf = SM->getCharacterData(DeclLoc);
4617     const char *argListBegin, *argListEnd;
4618     GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4619     while (argListBegin < argListEnd) {
4620       if (*argListBegin == '^')
4621         buf += '*';
4622       else if (*argListBegin ==  '<') {
4623         buf += "/*"; 
4624         buf += *argListBegin++;
4625         OrigLength++;;
4626         while (*argListBegin != '>') {
4627           buf += *argListBegin++;
4628           OrigLength++;
4629         }
4630         buf += *argListBegin;
4631         buf += "*/";
4632       }
4633       else
4634         buf += *argListBegin;
4635       argListBegin++;
4636       OrigLength++;
4637     }
4638     buf += ')';
4639     OrigLength++;
4640   }
4641   ReplaceText(Start, OrigLength, buf);
4642   
4643   return;
4644 }
4645
4646
4647 /// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
4648 /// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
4649 ///                    struct Block_byref_id_object *src) {
4650 ///  _Block_object_assign (&_dest->object, _src->object, 
4651 ///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
4652 ///                        [|BLOCK_FIELD_IS_WEAK]) // object
4653 ///  _Block_object_assign(&_dest->object, _src->object, 
4654 ///                       BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
4655 ///                       [|BLOCK_FIELD_IS_WEAK]) // block
4656 /// }
4657 /// And:
4658 /// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
4659 ///  _Block_object_dispose(_src->object, 
4660 ///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
4661 ///                        [|BLOCK_FIELD_IS_WEAK]) // object
4662 ///  _Block_object_dispose(_src->object, 
4663 ///                         BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
4664 ///                         [|BLOCK_FIELD_IS_WEAK]) // block
4665 /// }
4666
4667 std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
4668                                                           int flag) {
4669   std::string S;
4670   if (CopyDestroyCache.count(flag))
4671     return S;
4672   CopyDestroyCache.insert(flag);
4673   S = "static void __Block_byref_id_object_copy_";
4674   S += utostr(flag);
4675   S += "(void *dst, void *src) {\n";
4676   
4677   // offset into the object pointer is computed as:
4678   // void * + void* + int + int + void* + void *
4679   unsigned IntSize = 
4680   static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
4681   unsigned VoidPtrSize = 
4682   static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
4683   
4684   unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
4685   S += " _Block_object_assign((char*)dst + ";
4686   S += utostr(offset);
4687   S += ", *(void * *) ((char*)src + ";
4688   S += utostr(offset);
4689   S += "), ";
4690   S += utostr(flag);
4691   S += ");\n}\n";
4692   
4693   S += "static void __Block_byref_id_object_dispose_";
4694   S += utostr(flag);
4695   S += "(void *src) {\n";
4696   S += " _Block_object_dispose(*(void * *) ((char*)src + ";
4697   S += utostr(offset);
4698   S += "), ";
4699   S += utostr(flag);
4700   S += ");\n}\n";
4701   return S;
4702 }
4703
4704 /// RewriteByRefVar - For each __block typex ND variable this routine transforms
4705 /// the declaration into:
4706 /// struct __Block_byref_ND {
4707 /// void *__isa;                  // NULL for everything except __weak pointers
4708 /// struct __Block_byref_ND *__forwarding;
4709 /// int32_t __flags;
4710 /// int32_t __size;
4711 /// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
4712 /// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
4713 /// typex ND;
4714 /// };
4715 ///
4716 /// It then replaces declaration of ND variable with:
4717 /// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 
4718 ///                               __size=sizeof(struct __Block_byref_ND), 
4719 ///                               ND=initializer-if-any};
4720 ///
4721 ///
4722 void RewriteModernObjC::RewriteByRefVar(VarDecl *ND) {
4723   int flag = 0;
4724   int isa = 0;
4725   SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
4726   if (DeclLoc.isInvalid())
4727     // If type location is missing, it is because of missing type (a warning).
4728     // Use variable's location which is good for this case.
4729     DeclLoc = ND->getLocation();
4730   const char *startBuf = SM->getCharacterData(DeclLoc);
4731   SourceLocation X = ND->getLocEnd();
4732   X = SM->getExpansionLoc(X);
4733   const char *endBuf = SM->getCharacterData(X);
4734   std::string Name(ND->getNameAsString());
4735   std::string ByrefType;
4736   RewriteByRefString(ByrefType, Name, ND, true);
4737   ByrefType += " {\n";
4738   ByrefType += "  void *__isa;\n";
4739   RewriteByRefString(ByrefType, Name, ND);
4740   ByrefType += " *__forwarding;\n";
4741   ByrefType += " int __flags;\n";
4742   ByrefType += " int __size;\n";
4743   // Add void *__Block_byref_id_object_copy; 
4744   // void *__Block_byref_id_object_dispose; if needed.
4745   QualType Ty = ND->getType();
4746   bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty);
4747   if (HasCopyAndDispose) {
4748     ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n";
4749     ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n";
4750   }
4751
4752   QualType T = Ty;
4753   (void)convertBlockPointerToFunctionPointer(T);
4754   T.getAsStringInternal(Name, Context->getPrintingPolicy());
4755     
4756   ByrefType += " " + Name + ";\n";
4757   ByrefType += "};\n";
4758   // Insert this type in global scope. It is needed by helper function.
4759   SourceLocation FunLocStart;
4760   if (CurFunctionDef)
4761      FunLocStart = getFunctionSourceLocation(CurFunctionDef);
4762   else {
4763     assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
4764     FunLocStart = CurMethodDef->getLocStart();
4765   }
4766   InsertText(FunLocStart, ByrefType);
4767   if (Ty.isObjCGCWeak()) {
4768     flag |= BLOCK_FIELD_IS_WEAK;
4769     isa = 1;
4770   }
4771   
4772   if (HasCopyAndDispose) {
4773     flag = BLOCK_BYREF_CALLER;
4774     QualType Ty = ND->getType();
4775     // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
4776     if (Ty->isBlockPointerType())
4777       flag |= BLOCK_FIELD_IS_BLOCK;
4778     else
4779       flag |= BLOCK_FIELD_IS_OBJECT;
4780     std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
4781     if (!HF.empty())
4782       InsertText(FunLocStart, HF);
4783   }
4784   
4785   // struct __Block_byref_ND ND = 
4786   // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 
4787   //  initializer-if-any};
4788   bool hasInit = (ND->getInit() != 0);
4789   // FIXME. rewriter does not support __block c++ objects which
4790   // require construction.
4791   if (hasInit && dyn_cast<CXXConstructExpr>(ND->getInit()))
4792     hasInit = false;
4793   unsigned flags = 0;
4794   if (HasCopyAndDispose)
4795     flags |= BLOCK_HAS_COPY_DISPOSE;
4796   Name = ND->getNameAsString();
4797   ByrefType.clear();
4798   RewriteByRefString(ByrefType, Name, ND);
4799   std::string ForwardingCastType("(");
4800   ForwardingCastType += ByrefType + " *)";
4801   if (!hasInit) {
4802     ByrefType += " " + Name + " = {(void*)";
4803     ByrefType += utostr(isa);
4804     ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
4805     ByrefType += utostr(flags);
4806     ByrefType += ", ";
4807     ByrefType += "sizeof(";
4808     RewriteByRefString(ByrefType, Name, ND);
4809     ByrefType += ")";
4810     if (HasCopyAndDispose) {
4811       ByrefType += ", __Block_byref_id_object_copy_";
4812       ByrefType += utostr(flag);
4813       ByrefType += ", __Block_byref_id_object_dispose_";
4814       ByrefType += utostr(flag);
4815     }
4816     ByrefType += "};\n";
4817     unsigned nameSize = Name.size();
4818     // for block or function pointer declaration. Name is aleady
4819     // part of the declaration.
4820     if (Ty->isBlockPointerType() || Ty->isFunctionPointerType())
4821       nameSize = 1;
4822     ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
4823   }
4824   else {
4825     SourceLocation startLoc;
4826     Expr *E = ND->getInit();
4827     if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
4828       startLoc = ECE->getLParenLoc();
4829     else
4830       startLoc = E->getLocStart();
4831     startLoc = SM->getExpansionLoc(startLoc);
4832     endBuf = SM->getCharacterData(startLoc);
4833     ByrefType += " " + Name;
4834     ByrefType += " = {(void*)";
4835     ByrefType += utostr(isa);
4836     ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
4837     ByrefType += utostr(flags);
4838     ByrefType += ", ";
4839     ByrefType += "sizeof(";
4840     RewriteByRefString(ByrefType, Name, ND);
4841     ByrefType += "), ";
4842     if (HasCopyAndDispose) {
4843       ByrefType += "__Block_byref_id_object_copy_";
4844       ByrefType += utostr(flag);
4845       ByrefType += ", __Block_byref_id_object_dispose_";
4846       ByrefType += utostr(flag);
4847       ByrefType += ", ";
4848     }
4849     ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
4850     
4851     // Complete the newly synthesized compound expression by inserting a right
4852     // curly brace before the end of the declaration.
4853     // FIXME: This approach avoids rewriting the initializer expression. It
4854     // also assumes there is only one declarator. For example, the following
4855     // isn't currently supported by this routine (in general):
4856     // 
4857     // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37;
4858     //
4859     const char *startInitializerBuf = SM->getCharacterData(startLoc);
4860     const char *semiBuf = strchr(startInitializerBuf, ';');
4861     assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'");
4862     SourceLocation semiLoc =
4863       startLoc.getLocWithOffset(semiBuf-startInitializerBuf);
4864
4865     InsertText(semiLoc, "}");
4866   }
4867   return;
4868 }
4869
4870 void RewriteModernObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
4871   // Add initializers for any closure decl refs.
4872   GetBlockDeclRefExprs(Exp->getBody());
4873   if (BlockDeclRefs.size()) {
4874     // Unique all "by copy" declarations.
4875     for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
4876       if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
4877         if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
4878           BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
4879           BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
4880         }
4881       }
4882     // Unique all "by ref" declarations.
4883     for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
4884       if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
4885         if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
4886           BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
4887           BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
4888         }
4889       }
4890     // Find any imported blocks...they will need special attention.
4891     for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
4892       if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
4893           BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
4894           BlockDeclRefs[i]->getType()->isBlockPointerType())
4895         ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
4896   }
4897 }
4898
4899 FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
4900   IdentifierInfo *ID = &Context->Idents.get(name);
4901   QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
4902   return FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
4903                               SourceLocation(), ID, FType, 0, SC_Extern,
4904                               SC_None, false, false);
4905 }
4906
4907 Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
4908           const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs) {
4909   
4910   const BlockDecl *block = Exp->getBlockDecl();
4911   
4912   Blocks.push_back(Exp);
4913
4914   CollectBlockDeclRefInfo(Exp);
4915   
4916   // Add inner imported variables now used in current block.
4917  int countOfInnerDecls = 0;
4918   if (!InnerBlockDeclRefs.empty()) {
4919     for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
4920       DeclRefExpr *Exp = InnerBlockDeclRefs[i];
4921       ValueDecl *VD = Exp->getDecl();
4922       if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
4923       // We need to save the copied-in variables in nested
4924       // blocks because it is needed at the end for some of the API generations.
4925       // See SynthesizeBlockLiterals routine.
4926         InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
4927         BlockDeclRefs.push_back(Exp);
4928         BlockByCopyDeclsPtrSet.insert(VD);
4929         BlockByCopyDecls.push_back(VD);
4930       }
4931       if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
4932         InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
4933         BlockDeclRefs.push_back(Exp);
4934         BlockByRefDeclsPtrSet.insert(VD);
4935         BlockByRefDecls.push_back(VD);
4936       }
4937     }
4938     // Find any imported blocks...they will need special attention.
4939     for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
4940       if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
4941           InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
4942           InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
4943         ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
4944   }
4945   InnerDeclRefsCount.push_back(countOfInnerDecls);
4946   
4947   std::string FuncName;
4948
4949   if (CurFunctionDef)
4950     FuncName = CurFunctionDef->getNameAsString();
4951   else if (CurMethodDef)
4952     BuildUniqueMethodName(FuncName, CurMethodDef);
4953   else if (GlobalVarDecl)
4954     FuncName = std::string(GlobalVarDecl->getNameAsString());
4955
4956   bool GlobalBlockExpr = 
4957     block->getDeclContext()->getRedeclContext()->isFileContext();
4958   
4959   if (GlobalBlockExpr && !GlobalVarDecl) {
4960     Diags.Report(block->getLocation(), GlobalBlockRewriteFailedDiag);
4961     GlobalBlockExpr = false;
4962   }
4963   
4964   std::string BlockNumber = utostr(Blocks.size()-1);
4965
4966   std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
4967
4968   // Get a pointer to the function type so we can cast appropriately.
4969   QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
4970   QualType FType = Context->getPointerType(BFT);
4971
4972   FunctionDecl *FD;
4973   Expr *NewRep;
4974
4975   // Simulate a contructor call...
4976   std::string Tag;
4977   
4978   if (GlobalBlockExpr)
4979     Tag = "__global_";
4980   else
4981     Tag = "__";
4982   Tag += FuncName + "_block_impl_" + BlockNumber;
4983   
4984   FD = SynthBlockInitFunctionDecl(Tag);
4985   DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
4986                                                SourceLocation());
4987
4988   SmallVector<Expr*, 4> InitExprs;
4989
4990   // Initialize the block function.
4991   FD = SynthBlockInitFunctionDecl(Func);
4992   DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
4993                                                VK_LValue, SourceLocation());
4994   CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
4995                                                 CK_BitCast, Arg);
4996   InitExprs.push_back(castExpr);
4997
4998   // Initialize the block descriptor.
4999   std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA";
5000
5001   VarDecl *NewVD = VarDecl::Create(*Context, TUDecl,
5002                                    SourceLocation(), SourceLocation(),
5003                                    &Context->Idents.get(DescData.c_str()),
5004                                    Context->VoidPtrTy, 0,
5005                                    SC_Static, SC_None);
5006   UnaryOperator *DescRefExpr =
5007     new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
5008                                                           Context->VoidPtrTy,
5009                                                           VK_LValue,
5010                                                           SourceLocation()), 
5011                                 UO_AddrOf,
5012                                 Context->getPointerType(Context->VoidPtrTy), 
5013                                 VK_RValue, OK_Ordinary,
5014                                 SourceLocation());
5015   InitExprs.push_back(DescRefExpr); 
5016   
5017   // Add initializers for any closure decl refs.
5018   if (BlockDeclRefs.size()) {
5019     Expr *Exp;
5020     // Output all "by copy" declarations.
5021     for (SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
5022          E = BlockByCopyDecls.end(); I != E; ++I) {
5023       if (isObjCType((*I)->getType())) {
5024         // FIXME: Conform to ABI ([[obj retain] autorelease]).
5025         FD = SynthBlockInitFunctionDecl((*I)->getName());
5026         Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
5027                                         VK_LValue, SourceLocation());
5028         if (HasLocalVariableExternalStorage(*I)) {
5029           QualType QT = (*I)->getType();
5030           QT = Context->getPointerType(QT);
5031           Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
5032                                             OK_Ordinary, SourceLocation());
5033         }
5034       } else if (isTopLevelBlockPointerType((*I)->getType())) {
5035         FD = SynthBlockInitFunctionDecl((*I)->getName());
5036         Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
5037                                         VK_LValue, SourceLocation());
5038         Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
5039                                        CK_BitCast, Arg);
5040       } else {
5041         FD = SynthBlockInitFunctionDecl((*I)->getName());
5042         Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
5043                                         VK_LValue, SourceLocation());
5044         if (HasLocalVariableExternalStorage(*I)) {
5045           QualType QT = (*I)->getType();
5046           QT = Context->getPointerType(QT);
5047           Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
5048                                             OK_Ordinary, SourceLocation());
5049         }
5050         
5051       }
5052       InitExprs.push_back(Exp);
5053     }
5054     // Output all "by ref" declarations.
5055     for (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
5056          E = BlockByRefDecls.end(); I != E; ++I) {
5057       ValueDecl *ND = (*I);
5058       std::string Name(ND->getNameAsString());
5059       std::string RecName;
5060       RewriteByRefString(RecName, Name, ND, true);
5061       IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 
5062                                                 + sizeof("struct"));
5063       RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
5064                                           SourceLocation(), SourceLocation(),
5065                                           II);
5066       assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
5067       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
5068       
5069       FD = SynthBlockInitFunctionDecl((*I)->getName());
5070       Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
5071                                       SourceLocation());
5072       bool isNestedCapturedVar = false;
5073       if (block)
5074         for (BlockDecl::capture_const_iterator ci = block->capture_begin(),
5075              ce = block->capture_end(); ci != ce; ++ci) {
5076           const VarDecl *variable = ci->getVariable();
5077           if (variable == ND && ci->isNested()) {
5078             assert (ci->isByRef() && 
5079                     "SynthBlockInitExpr - captured block variable is not byref");
5080             isNestedCapturedVar = true;
5081             break;
5082           }
5083         }
5084       // captured nested byref variable has its address passed. Do not take
5085       // its address again.
5086       if (!isNestedCapturedVar)
5087           Exp = new (Context) UnaryOperator(Exp, UO_AddrOf,
5088                                      Context->getPointerType(Exp->getType()),
5089                                      VK_RValue, OK_Ordinary, SourceLocation());
5090       Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5091       InitExprs.push_back(Exp);
5092     }
5093   }
5094   if (ImportedBlockDecls.size()) {
5095     // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
5096     int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR);
5097     unsigned IntSize = 
5098       static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
5099     Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 
5100                                            Context->IntTy, SourceLocation());
5101     InitExprs.push_back(FlagExp);
5102   }
5103   NewRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(),
5104                                   FType, VK_LValue, SourceLocation());
5105   
5106   if (GlobalBlockExpr) {
5107     assert (GlobalConstructionExp == 0 && 
5108             "SynthBlockInitExpr - GlobalConstructionExp must be null");
5109     GlobalConstructionExp = NewRep;
5110     NewRep = DRE;
5111   }
5112   
5113   NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
5114                              Context->getPointerType(NewRep->getType()),
5115                              VK_RValue, OK_Ordinary, SourceLocation());
5116   NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5117                                     NewRep);
5118   BlockDeclRefs.clear();
5119   BlockByRefDecls.clear();
5120   BlockByRefDeclsPtrSet.clear();
5121   BlockByCopyDecls.clear();
5122   BlockByCopyDeclsPtrSet.clear();
5123   ImportedBlockDecls.clear();
5124   return NewRep;
5125 }
5126
5127 bool RewriteModernObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) {
5128   if (const ObjCForCollectionStmt * CS = 
5129       dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5130         return CS->getElement() == DS;
5131   return false;
5132 }
5133
5134 //===----------------------------------------------------------------------===//
5135 // Function Body / Expression rewriting
5136 //===----------------------------------------------------------------------===//
5137
5138 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
5139   if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5140       isa<DoStmt>(S) || isa<ForStmt>(S))
5141     Stmts.push_back(S);
5142   else if (isa<ObjCForCollectionStmt>(S)) {
5143     Stmts.push_back(S);
5144     ObjCBcLabelNo.push_back(++BcLabelCount);
5145   }
5146
5147   // Pseudo-object operations and ivar references need special
5148   // treatment because we're going to recursively rewrite them.
5149   if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) {
5150     if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) {
5151       return RewritePropertyOrImplicitSetter(PseudoOp);
5152     } else {
5153       return RewritePropertyOrImplicitGetter(PseudoOp);
5154     }
5155   } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5156     return RewriteObjCIvarRefExpr(IvarRefExpr);
5157   }
5158
5159   SourceRange OrigStmtRange = S->getSourceRange();
5160
5161   // Perform a bottom up rewrite of all children.
5162   for (Stmt::child_range CI = S->children(); CI; ++CI)
5163     if (*CI) {
5164       Stmt *childStmt = (*CI);
5165       Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5166       if (newStmt) {
5167         *CI = newStmt;
5168       }
5169     }
5170
5171   if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5172     SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
5173     llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
5174     InnerContexts.insert(BE->getBlockDecl());
5175     ImportedLocalExternalDecls.clear();
5176     GetInnerBlockDeclRefExprs(BE->getBody(),
5177                               InnerBlockDeclRefs, InnerContexts);
5178     // Rewrite the block body in place.
5179     Stmt *SaveCurrentBody = CurrentBody;
5180     CurrentBody = BE->getBody();
5181     PropParentMap = 0;
5182     // block literal on rhs of a property-dot-sytax assignment
5183     // must be replaced by its synthesize ast so getRewrittenText
5184     // works as expected. In this case, what actually ends up on RHS
5185     // is the blockTranscribed which is the helper function for the
5186     // block literal; as in: self.c = ^() {[ace ARR];};
5187     bool saveDisableReplaceStmt = DisableReplaceStmt;
5188     DisableReplaceStmt = false;
5189     RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5190     DisableReplaceStmt = saveDisableReplaceStmt;
5191     CurrentBody = SaveCurrentBody;
5192     PropParentMap = 0;
5193     ImportedLocalExternalDecls.clear();
5194     // Now we snarf the rewritten text and stash it away for later use.
5195     std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
5196     RewrittenBlockExprs[BE] = Str;
5197
5198     Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5199                             
5200     //blockTranscribed->dump();
5201     ReplaceStmt(S, blockTranscribed);
5202     return blockTranscribed;
5203   }
5204   // Handle specific things.
5205   if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
5206     return RewriteAtEncode(AtEncode);
5207
5208   if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
5209     return RewriteAtSelector(AtSelector);
5210
5211   if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
5212     return RewriteObjCStringLiteral(AtString);
5213   
5214   if (ObjCBoolLiteralExpr *BoolLitExpr = dyn_cast<ObjCBoolLiteralExpr>(S))
5215     return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5216   
5217   if (ObjCNumericLiteral *NumericLitExpr = dyn_cast<ObjCNumericLiteral>(S))
5218     return RewriteObjCNumericLiteralExpr(NumericLitExpr);
5219   
5220   if (ObjCArrayLiteral *ArrayLitExpr = dyn_cast<ObjCArrayLiteral>(S))
5221     return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5222   
5223   if (ObjCDictionaryLiteral *DictionaryLitExpr = 
5224         dyn_cast<ObjCDictionaryLiteral>(S))
5225     return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5226
5227   if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
5228 #if 0
5229     // Before we rewrite it, put the original message expression in a comment.
5230     SourceLocation startLoc = MessExpr->getLocStart();
5231     SourceLocation endLoc = MessExpr->getLocEnd();
5232
5233     const char *startBuf = SM->getCharacterData(startLoc);
5234     const char *endBuf = SM->getCharacterData(endLoc);
5235
5236     std::string messString;
5237     messString += "// ";
5238     messString.append(startBuf, endBuf-startBuf+1);
5239     messString += "\n";
5240
5241     // FIXME: Missing definition of
5242     // InsertText(clang::SourceLocation, char const*, unsigned int).
5243     // InsertText(startLoc, messString.c_str(), messString.size());
5244     // Tried this, but it didn't work either...
5245     // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
5246 #endif
5247     return RewriteMessageExpr(MessExpr);
5248   }
5249
5250   if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
5251     return RewriteObjCTryStmt(StmtTry);
5252
5253   if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
5254     return RewriteObjCSynchronizedStmt(StmtTry);
5255
5256   if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
5257     return RewriteObjCThrowStmt(StmtThrow);
5258
5259   if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
5260     return RewriteObjCProtocolExpr(ProtocolExp);
5261
5262   if (ObjCForCollectionStmt *StmtForCollection =
5263         dyn_cast<ObjCForCollectionStmt>(S))
5264     return RewriteObjCForCollectionStmt(StmtForCollection,
5265                                         OrigStmtRange.getEnd());
5266   if (BreakStmt *StmtBreakStmt =
5267       dyn_cast<BreakStmt>(S))
5268     return RewriteBreakStmt(StmtBreakStmt);
5269   if (ContinueStmt *StmtContinueStmt =
5270       dyn_cast<ContinueStmt>(S))
5271     return RewriteContinueStmt(StmtContinueStmt);
5272
5273   // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
5274   // and cast exprs.
5275   if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5276     // FIXME: What we're doing here is modifying the type-specifier that
5277     // precedes the first Decl.  In the future the DeclGroup should have
5278     // a separate type-specifier that we can rewrite.
5279     // NOTE: We need to avoid rewriting the DeclStmt if it is within
5280     // the context of an ObjCForCollectionStmt. For example:
5281     //   NSArray *someArray;
5282     //   for (id <FooProtocol> index in someArray) ;
5283     // This is because RewriteObjCForCollectionStmt() does textual rewriting 
5284     // and it depends on the original text locations/positions.
5285     if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5286       RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin());
5287
5288     // Blocks rewrite rules.
5289     for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
5290          DI != DE; ++DI) {
5291       Decl *SD = *DI;
5292       if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5293         if (isTopLevelBlockPointerType(ND->getType()))
5294           RewriteBlockPointerDecl(ND);
5295         else if (ND->getType()->isFunctionPointerType())
5296           CheckFunctionPointerDecl(ND->getType(), ND);
5297         if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5298           if (VD->hasAttr<BlocksAttr>()) {
5299             static unsigned uniqueByrefDeclCount = 0;
5300             assert(!BlockByRefDeclNo.count(ND) &&
5301               "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5302             BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5303             RewriteByRefVar(VD);
5304           }
5305           else           
5306             RewriteTypeOfDecl(VD);
5307         }
5308       }
5309       if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) {
5310         if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5311           RewriteBlockPointerDecl(TD);
5312         else if (TD->getUnderlyingType()->isFunctionPointerType())
5313           CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5314       }
5315     }
5316   }
5317
5318   if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S))
5319     RewriteObjCQualifiedInterfaceTypes(CE);
5320
5321   if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5322       isa<DoStmt>(S) || isa<ForStmt>(S)) {
5323     assert(!Stmts.empty() && "Statement stack is empty");
5324     assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5325              isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5326             && "Statement stack mismatch");
5327     Stmts.pop_back();
5328   }
5329   // Handle blocks rewriting.
5330   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5331     ValueDecl *VD = DRE->getDecl(); 
5332     if (VD->hasAttr<BlocksAttr>())
5333       return RewriteBlockDeclRefExpr(DRE);
5334     if (HasLocalVariableExternalStorage(VD))
5335       return RewriteLocalVariableExternalStorage(DRE);
5336   }
5337   
5338   if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
5339     if (CE->getCallee()->getType()->isBlockPointerType()) {
5340       Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
5341       ReplaceStmt(S, BlockCall);
5342       return BlockCall;
5343     }
5344   }
5345   if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) {
5346     RewriteCastExpr(CE);
5347   }
5348   if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
5349     RewriteImplicitCastObjCExpr(ICE);
5350   }
5351 #if 0
5352
5353   if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
5354     CastExpr *Replacement = new (Context) CastExpr(ICE->getType(),
5355                                                    ICE->getSubExpr(),
5356                                                    SourceLocation());
5357     // Get the new text.
5358     std::string SStr;
5359     llvm::raw_string_ostream Buf(SStr);
5360     Replacement->printPretty(Buf, *Context);
5361     const std::string &Str = Buf.str();
5362
5363     printf("CAST = %s\n", &Str[0]);
5364     InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
5365     delete S;
5366     return Replacement;
5367   }
5368 #endif
5369   // Return this stmt unmodified.
5370   return S;
5371 }
5372
5373 void RewriteModernObjC::RewriteRecordBody(RecordDecl *RD) {
5374   for (RecordDecl::field_iterator i = RD->field_begin(), 
5375                                   e = RD->field_end(); i != e; ++i) {
5376     FieldDecl *FD = *i;
5377     if (isTopLevelBlockPointerType(FD->getType()))
5378       RewriteBlockPointerDecl(FD);
5379     if (FD->getType()->isObjCQualifiedIdType() ||
5380         FD->getType()->isObjCQualifiedInterfaceType())
5381       RewriteObjCQualifiedInterfaceTypes(FD);
5382   }
5383 }
5384
5385 /// HandleDeclInMainFile - This is called for each top-level decl defined in the
5386 /// main file of the input.
5387 void RewriteModernObjC::HandleDeclInMainFile(Decl *D) {
5388   switch (D->getKind()) {
5389     case Decl::Function: {
5390       FunctionDecl *FD = cast<FunctionDecl>(D);
5391       if (FD->isOverloadedOperator())
5392         return;
5393
5394       // Since function prototypes don't have ParmDecl's, we check the function
5395       // prototype. This enables us to rewrite function declarations and
5396       // definitions using the same code.
5397       RewriteBlocksInFunctionProtoType(FD->getType(), FD);
5398
5399       if (!FD->isThisDeclarationADefinition())
5400         break;
5401
5402       // FIXME: If this should support Obj-C++, support CXXTryStmt
5403       if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
5404         CurFunctionDef = FD;
5405         CurFunctionDeclToDeclareForBlock = FD;
5406         CurrentBody = Body;
5407         Body =
5408         cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5409         FD->setBody(Body);
5410         CurrentBody = 0;
5411         if (PropParentMap) {
5412           delete PropParentMap;
5413           PropParentMap = 0;
5414         }
5415         // This synthesizes and inserts the block "impl" struct, invoke function,
5416         // and any copy/dispose helper functions.
5417         InsertBlockLiteralsWithinFunction(FD);
5418         CurFunctionDef = 0;
5419         CurFunctionDeclToDeclareForBlock = 0;
5420       }
5421       break;
5422     }
5423     case Decl::ObjCMethod: {
5424       ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
5425       if (CompoundStmt *Body = MD->getCompoundBody()) {
5426         CurMethodDef = MD;
5427         CurrentBody = Body;
5428         Body =
5429           cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5430         MD->setBody(Body);
5431         CurrentBody = 0;
5432         if (PropParentMap) {
5433           delete PropParentMap;
5434           PropParentMap = 0;
5435         }
5436         InsertBlockLiteralsWithinMethod(MD);
5437         CurMethodDef = 0;
5438       }
5439       break;
5440     }
5441     case Decl::ObjCImplementation: {
5442       ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D);
5443       ClassImplementation.push_back(CI);
5444       break;
5445     }
5446     case Decl::ObjCCategoryImpl: {
5447       ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D);
5448       CategoryImplementation.push_back(CI);
5449       break;
5450     }
5451     case Decl::Var: {
5452       VarDecl *VD = cast<VarDecl>(D);
5453       RewriteObjCQualifiedInterfaceTypes(VD);
5454       if (isTopLevelBlockPointerType(VD->getType()))
5455         RewriteBlockPointerDecl(VD);
5456       else if (VD->getType()->isFunctionPointerType()) {
5457         CheckFunctionPointerDecl(VD->getType(), VD);
5458         if (VD->getInit()) {
5459           if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
5460             RewriteCastExpr(CE);
5461           }
5462         }
5463       } else if (VD->getType()->isRecordType()) {
5464         RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl();
5465         if (RD->isCompleteDefinition())
5466           RewriteRecordBody(RD);
5467       }
5468       if (VD->getInit()) {
5469         GlobalVarDecl = VD;
5470         CurrentBody = VD->getInit();
5471         RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
5472         CurrentBody = 0;
5473         if (PropParentMap) {
5474           delete PropParentMap;
5475           PropParentMap = 0;
5476         }
5477         SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName());
5478         GlobalVarDecl = 0;
5479           
5480         // This is needed for blocks.
5481         if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
5482             RewriteCastExpr(CE);
5483         }
5484       }
5485       break;
5486     }
5487     case Decl::TypeAlias:
5488     case Decl::Typedef: {
5489       if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
5490         if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5491           RewriteBlockPointerDecl(TD);
5492         else if (TD->getUnderlyingType()->isFunctionPointerType())
5493           CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5494       }
5495       break;
5496     }
5497     case Decl::CXXRecord:
5498     case Decl::Record: {
5499       RecordDecl *RD = cast<RecordDecl>(D);
5500       if (RD->isCompleteDefinition()) 
5501         RewriteRecordBody(RD);
5502       break;
5503     }
5504     default:
5505       break;
5506   }
5507   // Nothing yet.
5508 }
5509
5510 /// Write_ProtocolExprReferencedMetadata - This routine writer out the
5511 /// protocol reference symbols in the for of:
5512 /// struct _protocol_t *PROTOCOL_REF = &PROTOCOL_METADATA.
5513 static void Write_ProtocolExprReferencedMetadata(ASTContext *Context, 
5514                                                  ObjCProtocolDecl *PDecl,
5515                                                  std::string &Result) {
5516   // Also output .objc_protorefs$B section and its meta-data.
5517   if (Context->getLangOpts().MicrosoftExt)
5518     Result += "__declspec(allocate(\".objc_protorefs$B\")) ";
5519   Result += "struct _protocol_t *";
5520   Result += "_OBJC_PROTOCOL_REFERENCE_$_";
5521   Result += PDecl->getNameAsString();
5522   Result += " = &";
5523   Result += "_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
5524   Result += ";\n";
5525 }
5526
5527 void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) {
5528   if (Diags.hasErrorOccurred())
5529     return;
5530
5531   RewriteInclude();
5532
5533   // Here's a great place to add any extra declarations that may be needed.
5534   // Write out meta data for each @protocol(<expr>).
5535   for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
5536        E = ProtocolExprDecls.end(); I != E; ++I) {
5537     RewriteObjCProtocolMetaData(*I, Preamble);
5538     Write_ProtocolExprReferencedMetadata(Context, (*I), Preamble);
5539   }
5540
5541   InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
5542   for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5543     ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
5544     // Write struct declaration for the class matching its ivar declarations.
5545     // Note that for modern abi, this is postponed until the end of TU
5546     // because class extensions and the implementation might declare their own
5547     // private ivars.
5548     RewriteInterfaceDecl(CDecl);
5549   }
5550   
5551   if (ClassImplementation.size() || CategoryImplementation.size())
5552     RewriteImplementations();
5553
5554   // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
5555   // we are done.
5556   if (const RewriteBuffer *RewriteBuf =
5557       Rewrite.getRewriteBufferFor(MainFileID)) {
5558     //printf("Changed:\n");
5559     *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5560   } else {
5561     llvm::errs() << "No changes\n";
5562   }
5563
5564   if (ClassImplementation.size() || CategoryImplementation.size() ||
5565       ProtocolExprDecls.size()) {
5566     // Rewrite Objective-c meta data*
5567     std::string ResultStr;
5568     RewriteMetaDataIntoBuffer(ResultStr);
5569     // Emit metadata.
5570     *OutFile << ResultStr;
5571   }
5572   // Emit ImageInfo;
5573   {
5574     std::string ResultStr;
5575     WriteImageInfo(ResultStr);
5576     *OutFile << ResultStr;
5577   }
5578   OutFile->flush();
5579 }
5580
5581 void RewriteModernObjC::Initialize(ASTContext &context) {
5582   InitializeCommon(context);
5583   
5584   Preamble += "#ifndef __OBJC2__\n";
5585   Preamble += "#define __OBJC2__\n";
5586   Preamble += "#endif\n";
5587
5588   // declaring objc_selector outside the parameter list removes a silly
5589   // scope related warning...
5590   if (IsHeader)
5591     Preamble = "#pragma once\n";
5592   Preamble += "struct objc_selector; struct objc_class;\n";
5593   Preamble += "struct __rw_objc_super { \n\tstruct objc_object *object; ";
5594   Preamble += "\n\tstruct objc_object *superClass; ";
5595   // Add a constructor for creating temporary objects.
5596   Preamble += "\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5597   Preamble += ": object(o), superClass(s) {} ";
5598   Preamble += "\n};\n";
5599   
5600   if (LangOpts.MicrosoftExt) {
5601     // Define all sections using syntax that makes sense.
5602     // These are currently generated.
5603     Preamble += "\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5604     Preamble += "#pragma section(\".objc_catlist$B\", long, read, write)\n";
5605     Preamble += "#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5606     Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5607     Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5608     Preamble += "#pragma section(\".objc_protorefs$B\", long, read, write)\n";
5609     // These are generated but not necessary for functionality.
5610     Preamble += "#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5611     Preamble += "#pragma section(\".inst_meth$B\", long, read, write)\n";
5612     Preamble += "#pragma section(\".cls_meth$B\", long, read, write)\n";
5613     Preamble += "#pragma section(\".objc_ivar$B\", long, read, write)\n";
5614     
5615     // These need be generated for performance. Currently they are not,
5616     // using API calls instead.
5617     Preamble += "#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5618     Preamble += "#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5619     Preamble += "#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5620     
5621   }
5622   Preamble += "#ifndef _REWRITER_typedef_Protocol\n";
5623   Preamble += "typedef struct objc_object Protocol;\n";
5624   Preamble += "#define _REWRITER_typedef_Protocol\n";
5625   Preamble += "#endif\n";
5626   if (LangOpts.MicrosoftExt) {
5627     Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5628     Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5629   } 
5630   else
5631     Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
5632   
5633   Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5634   Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5635   Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5636   Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5637   Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5638
5639   Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass";
5640   Preamble += "(const char *);\n";
5641   Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5642   Preamble += "(struct objc_class *);\n";
5643   Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
5644   Preamble += "(const char *);\n";
5645   Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5646   // @synchronized hooks.
5647   Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_enter( struct objc_object *);\n";
5648   Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_exit( struct objc_object *);\n";
5649   Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5650   Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
5651   Preamble += "struct __objcFastEnumerationState {\n\t";
5652   Preamble += "unsigned long state;\n\t";
5653   Preamble += "void **itemsPtr;\n\t";
5654   Preamble += "unsigned long *mutationsPtr;\n\t";
5655   Preamble += "unsigned long extra[5];\n};\n";
5656   Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5657   Preamble += "#define __FASTENUMERATIONSTATE\n";
5658   Preamble += "#endif\n";
5659   Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n";
5660   Preamble += "struct __NSConstantStringImpl {\n";
5661   Preamble += "  int *isa;\n";
5662   Preamble += "  int flags;\n";
5663   Preamble += "  char *str;\n";
5664   Preamble += "  long length;\n";
5665   Preamble += "};\n";
5666   Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n";
5667   Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5668   Preamble += "#else\n";
5669   Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5670   Preamble += "#endif\n";
5671   Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
5672   Preamble += "#endif\n";
5673   // Blocks preamble.
5674   Preamble += "#ifndef BLOCK_IMPL\n";
5675   Preamble += "#define BLOCK_IMPL\n";
5676   Preamble += "struct __block_impl {\n";
5677   Preamble += "  void *isa;\n";
5678   Preamble += "  int Flags;\n";
5679   Preamble += "  int Reserved;\n";
5680   Preamble += "  void *FuncPtr;\n";
5681   Preamble += "};\n";
5682   Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
5683   Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n";
5684   Preamble += "extern \"C\" __declspec(dllexport) "
5685   "void _Block_object_assign(void *, const void *, const int);\n";
5686   Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
5687   Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
5688   Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
5689   Preamble += "#else\n";
5690   Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
5691   Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
5692   Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
5693   Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
5694   Preamble += "#endif\n";
5695   Preamble += "#endif\n";
5696   if (LangOpts.MicrosoftExt) {
5697     Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
5698     Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
5699     Preamble += "#ifndef KEEP_ATTRIBUTES\n";  // We use this for clang tests.
5700     Preamble += "#define __attribute__(X)\n";
5701     Preamble += "#endif\n";
5702     Preamble += "#ifndef __weak\n";
5703     Preamble += "#define __weak\n";
5704     Preamble += "#endif\n";
5705     Preamble += "#ifndef __block\n";
5706     Preamble += "#define __block\n";
5707     Preamble += "#endif\n";
5708   }
5709   else {
5710     Preamble += "#define __block\n";
5711     Preamble += "#define __weak\n";
5712   }
5713   
5714   // Declarations required for modern objective-c array and dictionary literals.
5715   Preamble += "\n#include <stdarg.h>\n";
5716   Preamble += "struct __NSContainer_literal {\n";
5717   Preamble += "  void * *arr;\n";
5718   Preamble += "  __NSContainer_literal (unsigned int count, ...) {\n";
5719   Preamble += "\tva_list marker;\n";
5720   Preamble += "\tva_start(marker, count);\n";
5721   Preamble += "\tarr = new void *[count];\n";
5722   Preamble += "\tfor (unsigned i = 0; i < count; i++)\n";
5723   Preamble += "\t  arr[i] = va_arg(marker, void *);\n";
5724   Preamble += "\tva_end( marker );\n";
5725   Preamble += "  };\n";
5726   Preamble += "  __NSContainer_literal() {\n";
5727   Preamble += "\tdelete[] arr;\n";
5728   Preamble += "  }\n";
5729   Preamble += "};\n";
5730   
5731   // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
5732   // as this avoids warning in any 64bit/32bit compilation model.
5733   Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
5734 }
5735
5736 /// RewriteIvarOffsetComputation - This rutine synthesizes computation of
5737 /// ivar offset.
5738 void RewriteModernObjC::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
5739                                                          std::string &Result) {
5740   if (ivar->isBitField()) {
5741     // FIXME: The hack below doesn't work for bitfields. For now, we simply
5742     // place all bitfields at offset 0.
5743     Result += "0";
5744   } else {
5745     Result += "__OFFSETOFIVAR__(struct ";
5746     Result += ivar->getContainingInterface()->getNameAsString();
5747     if (LangOpts.MicrosoftExt)
5748       Result += "_IMPL";
5749     Result += ", ";
5750     Result += ivar->getNameAsString();
5751     Result += ")";
5752   }
5753 }
5754
5755 /// WriteModernMetadataDeclarations - Writes out metadata declarations for modern ABI.
5756 /// struct _prop_t {
5757 ///   const char *name;
5758 ///   char *attributes;
5759 /// }
5760
5761 /// struct _prop_list_t {
5762 ///   uint32_t entsize;      // sizeof(struct _prop_t)
5763 ///   uint32_t count_of_properties;
5764 ///   struct _prop_t prop_list[count_of_properties];
5765 /// }
5766
5767 /// struct _protocol_t;
5768
5769 /// struct _protocol_list_t {
5770 ///   long protocol_count;   // Note, this is 32/64 bit
5771 ///   struct _protocol_t * protocol_list[protocol_count];
5772 /// }
5773
5774 /// struct _objc_method {
5775 ///   SEL _cmd;
5776 ///   const char *method_type;
5777 ///   char *_imp;
5778 /// }
5779
5780 /// struct _method_list_t {
5781 ///   uint32_t entsize;  // sizeof(struct _objc_method)
5782 ///   uint32_t method_count;
5783 ///   struct _objc_method method_list[method_count];
5784 /// }
5785
5786 /// struct _protocol_t {
5787 ///   id isa;  // NULL
5788 ///   const char *protocol_name;
5789 ///   const struct _protocol_list_t * protocol_list; // super protocols
5790 ///   const struct method_list_t *instance_methods;
5791 ///   const struct method_list_t *class_methods;
5792 ///   const struct method_list_t *optionalInstanceMethods;
5793 ///   const struct method_list_t *optionalClassMethods;
5794 ///   const struct _prop_list_t * properties;
5795 ///   const uint32_t size;  // sizeof(struct _protocol_t)
5796 ///   const uint32_t flags;  // = 0
5797 ///   const char ** extendedMethodTypes;
5798 /// }
5799
5800 /// struct _ivar_t {
5801 ///   unsigned long int *offset;  // pointer to ivar offset location
5802 ///   const char *name;
5803 ///   const char *type;
5804 ///   uint32_t alignment;
5805 ///   uint32_t size;
5806 /// }
5807
5808 /// struct _ivar_list_t {
5809 ///   uint32 entsize;  // sizeof(struct _ivar_t)
5810 ///   uint32 count;
5811 ///   struct _ivar_t list[count];
5812 /// }
5813
5814 /// struct _class_ro_t {
5815 ///   uint32_t flags;
5816 ///   uint32_t instanceStart;
5817 ///   uint32_t instanceSize;
5818 ///   uint32_t reserved;  // only when building for 64bit targets
5819 ///   const uint8_t *ivarLayout;
5820 ///   const char *name;
5821 ///   const struct _method_list_t *baseMethods;
5822 ///   const struct _protocol_list_t *baseProtocols;
5823 ///   const struct _ivar_list_t *ivars;
5824 ///   const uint8_t *weakIvarLayout;
5825 ///   const struct _prop_list_t *properties;
5826 /// }
5827
5828 /// struct _class_t {
5829 ///   struct _class_t *isa;
5830 ///   struct _class_t *superclass;
5831 ///   void *cache;
5832 ///   IMP *vtable;
5833 ///   struct _class_ro_t *ro;
5834 /// }
5835
5836 /// struct _category_t {
5837 ///   const char *name;
5838 ///   struct _class_t *cls;
5839 ///   const struct _method_list_t *instance_methods;
5840 ///   const struct _method_list_t *class_methods;
5841 ///   const struct _protocol_list_t *protocols;
5842 ///   const struct _prop_list_t *properties;
5843 /// }
5844
5845 /// MessageRefTy - LLVM for:
5846 /// struct _message_ref_t {
5847 ///   IMP messenger;
5848 ///   SEL name;
5849 /// };
5850
5851 /// SuperMessageRefTy - LLVM for:
5852 /// struct _super_message_ref_t {
5853 ///   SUPER_IMP messenger;
5854 ///   SEL name;
5855 /// };
5856
5857 static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result) {
5858   static bool meta_data_declared = false;
5859   if (meta_data_declared)
5860     return;
5861   
5862   Result += "\nstruct _prop_t {\n";
5863   Result += "\tconst char *name;\n";
5864   Result += "\tconst char *attributes;\n";
5865   Result += "};\n";
5866   
5867   Result += "\nstruct _protocol_t;\n";
5868   
5869   Result += "\nstruct _objc_method {\n";
5870   Result += "\tstruct objc_selector * _cmd;\n";
5871   Result += "\tconst char *method_type;\n";
5872   Result += "\tvoid  *_imp;\n";
5873   Result += "};\n";
5874   
5875   Result += "\nstruct _protocol_t {\n";
5876   Result += "\tvoid * isa;  // NULL\n";
5877   Result += "\tconst char *protocol_name;\n";
5878   Result += "\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
5879   Result += "\tconst struct method_list_t *instance_methods;\n";
5880   Result += "\tconst struct method_list_t *class_methods;\n";
5881   Result += "\tconst struct method_list_t *optionalInstanceMethods;\n";
5882   Result += "\tconst struct method_list_t *optionalClassMethods;\n";
5883   Result += "\tconst struct _prop_list_t * properties;\n";
5884   Result += "\tconst unsigned int size;  // sizeof(struct _protocol_t)\n";
5885   Result += "\tconst unsigned int flags;  // = 0\n";
5886   Result += "\tconst char ** extendedMethodTypes;\n";
5887   Result += "};\n";
5888   
5889   Result += "\nstruct _ivar_t {\n";
5890   Result += "\tunsigned long int *offset;  // pointer to ivar offset location\n";
5891   Result += "\tconst char *name;\n";
5892   Result += "\tconst char *type;\n";
5893   Result += "\tunsigned int alignment;\n";
5894   Result += "\tunsigned int  size;\n";
5895   Result += "};\n";
5896   
5897   Result += "\nstruct _class_ro_t {\n";
5898   Result += "\tunsigned int flags;\n";
5899   Result += "\tunsigned int instanceStart;\n";
5900   Result += "\tunsigned int instanceSize;\n";
5901   const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
5902   if (Triple.getArch() == llvm::Triple::x86_64)
5903     Result += "\tunsigned int reserved;\n";
5904   Result += "\tconst unsigned char *ivarLayout;\n";
5905   Result += "\tconst char *name;\n";
5906   Result += "\tconst struct _method_list_t *baseMethods;\n";
5907   Result += "\tconst struct _objc_protocol_list *baseProtocols;\n";
5908   Result += "\tconst struct _ivar_list_t *ivars;\n";
5909   Result += "\tconst unsigned char *weakIvarLayout;\n";
5910   Result += "\tconst struct _prop_list_t *properties;\n";
5911   Result += "};\n";
5912   
5913   Result += "\nstruct _class_t {\n";
5914   Result += "\tstruct _class_t *isa;\n";
5915   Result += "\tstruct _class_t *superclass;\n";
5916   Result += "\tvoid *cache;\n";
5917   Result += "\tvoid *vtable;\n";
5918   Result += "\tstruct _class_ro_t *ro;\n";
5919   Result += "};\n";
5920   
5921   Result += "\nstruct _category_t {\n";
5922   Result += "\tconst char *name;\n";
5923   Result += "\tstruct _class_t *cls;\n";
5924   Result += "\tconst struct _method_list_t *instance_methods;\n";
5925   Result += "\tconst struct _method_list_t *class_methods;\n";
5926   Result += "\tconst struct _protocol_list_t *protocols;\n";
5927   Result += "\tconst struct _prop_list_t *properties;\n";
5928   Result += "};\n";
5929   
5930   Result += "extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
5931   Result += "#pragma warning(disable:4273)\n";
5932   meta_data_declared = true;
5933 }
5934
5935 static void Write_protocol_list_t_TypeDecl(std::string &Result,
5936                                            long super_protocol_count) {
5937   Result += "struct /*_protocol_list_t*/"; Result += " {\n";
5938   Result += "\tlong protocol_count;  // Note, this is 32/64 bit\n";
5939   Result += "\tstruct _protocol_t *super_protocols[";
5940   Result += utostr(super_protocol_count); Result += "];\n";
5941   Result += "}";
5942 }
5943
5944 static void Write_method_list_t_TypeDecl(std::string &Result,
5945                                          unsigned int method_count) {
5946   Result += "struct /*_method_list_t*/"; Result += " {\n";
5947   Result += "\tunsigned int entsize;  // sizeof(struct _objc_method)\n";
5948   Result += "\tunsigned int method_count;\n";
5949   Result += "\tstruct _objc_method method_list[";
5950   Result += utostr(method_count); Result += "];\n";
5951   Result += "}";
5952 }
5953
5954 static void Write__prop_list_t_TypeDecl(std::string &Result,
5955                                         unsigned int property_count) {
5956   Result += "struct /*_prop_list_t*/"; Result += " {\n";
5957   Result += "\tunsigned int entsize;  // sizeof(struct _prop_t)\n";
5958   Result += "\tunsigned int count_of_properties;\n";
5959   Result += "\tstruct _prop_t prop_list[";
5960   Result += utostr(property_count); Result += "];\n";
5961   Result += "}";
5962 }
5963
5964 static void Write__ivar_list_t_TypeDecl(std::string &Result,
5965                                         unsigned int ivar_count) {
5966   Result += "struct /*_ivar_list_t*/"; Result += " {\n";
5967   Result += "\tunsigned int entsize;  // sizeof(struct _prop_t)\n";
5968   Result += "\tunsigned int count;\n";
5969   Result += "\tstruct _ivar_t ivar_list[";
5970   Result += utostr(ivar_count); Result += "];\n";
5971   Result += "}";
5972 }
5973
5974 static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result,
5975                                             ArrayRef<ObjCProtocolDecl *> SuperProtocols,
5976                                             StringRef VarName,
5977                                             StringRef ProtocolName) {
5978   if (SuperProtocols.size() > 0) {
5979     Result += "\nstatic ";
5980     Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
5981     Result += " "; Result += VarName;
5982     Result += ProtocolName; 
5983     Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
5984     Result += "\t"; Result += utostr(SuperProtocols.size()); Result += ",\n";
5985     for (unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
5986       ObjCProtocolDecl *SuperPD = SuperProtocols[i];
5987       Result += "\t&"; Result += "_OBJC_PROTOCOL_"; 
5988       Result += SuperPD->getNameAsString();
5989       if (i == e-1)
5990         Result += "\n};\n";
5991       else
5992         Result += ",\n";
5993     }
5994   }
5995 }
5996
5997 static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
5998                                             ASTContext *Context, std::string &Result,
5999                                             ArrayRef<ObjCMethodDecl *> Methods,
6000                                             StringRef VarName,
6001                                             StringRef TopLevelDeclName,
6002                                             bool MethodImpl) {
6003   if (Methods.size() > 0) {
6004     Result += "\nstatic ";
6005     Write_method_list_t_TypeDecl(Result, Methods.size());
6006     Result += " "; Result += VarName;
6007     Result += TopLevelDeclName; 
6008     Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6009     Result += "\t"; Result += "sizeof(_objc_method)"; Result += ",\n";
6010     Result += "\t"; Result += utostr(Methods.size()); Result += ",\n";
6011     for (unsigned i = 0, e = Methods.size(); i < e; i++) {
6012       ObjCMethodDecl *MD = Methods[i];
6013       if (i == 0)
6014         Result += "\t{{(struct objc_selector *)\"";
6015       else
6016         Result += "\t{(struct objc_selector *)\"";
6017       Result += (MD)->getSelector().getAsString(); Result += "\"";
6018       Result += ", ";
6019       std::string MethodTypeString;
6020       Context->getObjCEncodingForMethodDecl(MD, MethodTypeString);
6021       Result += "\""; Result += MethodTypeString; Result += "\"";
6022       Result += ", ";
6023       if (!MethodImpl)
6024         Result += "0";
6025       else {
6026         Result += "(void *)";
6027         Result += RewriteObj.MethodInternalNames[MD];
6028       }
6029       if (i  == e-1)
6030         Result += "}}\n";
6031       else
6032         Result += "},\n";
6033     }
6034     Result += "};\n";
6035   }
6036 }
6037
6038 static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
6039                                            ASTContext *Context, std::string &Result,
6040                                            ArrayRef<ObjCPropertyDecl *> Properties,
6041                                            const Decl *Container,
6042                                            StringRef VarName,
6043                                            StringRef ProtocolName) {
6044   if (Properties.size() > 0) {
6045     Result += "\nstatic ";
6046     Write__prop_list_t_TypeDecl(Result, Properties.size());
6047     Result += " "; Result += VarName;
6048     Result += ProtocolName; 
6049     Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6050     Result += "\t"; Result += "sizeof(_prop_t)"; Result += ",\n";
6051     Result += "\t"; Result += utostr(Properties.size()); Result += ",\n";
6052     for (unsigned i = 0, e = Properties.size(); i < e; i++) {
6053       ObjCPropertyDecl *PropDecl = Properties[i];
6054       if (i == 0)
6055         Result += "\t{{\"";
6056       else
6057         Result += "\t{\"";
6058       Result += PropDecl->getName(); Result += "\",";
6059       std::string PropertyTypeString, QuotePropertyTypeString;
6060       Context->getObjCEncodingForPropertyDecl(PropDecl, Container, PropertyTypeString);
6061       RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6062       Result += "\""; Result += QuotePropertyTypeString; Result += "\"";
6063       if (i  == e-1)
6064         Result += "}}\n";
6065       else
6066         Result += "},\n";
6067     }
6068     Result += "};\n";
6069   }
6070 }
6071
6072 // Metadata flags
6073 enum MetaDataDlags {
6074   CLS = 0x0,
6075   CLS_META = 0x1,
6076   CLS_ROOT = 0x2,
6077   OBJC2_CLS_HIDDEN = 0x10,
6078   CLS_EXCEPTION = 0x20,
6079   
6080   /// (Obsolete) ARC-specific: this class has a .release_ivars method
6081   CLS_HAS_IVAR_RELEASER = 0x40,
6082   /// class was compiled with -fobjc-arr
6083   CLS_COMPILED_BY_ARC = 0x80  // (1<<7)
6084 };
6085
6086 static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result, 
6087                                           unsigned int flags, 
6088                                           const std::string &InstanceStart, 
6089                                           const std::string &InstanceSize,
6090                                           ArrayRef<ObjCMethodDecl *>baseMethods,
6091                                           ArrayRef<ObjCProtocolDecl *>baseProtocols,
6092                                           ArrayRef<ObjCIvarDecl *>ivars,
6093                                           ArrayRef<ObjCPropertyDecl *>Properties,
6094                                           StringRef VarName,
6095                                           StringRef ClassName) {
6096   Result += "\nstatic struct _class_ro_t ";
6097   Result += VarName; Result += ClassName;
6098   Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6099   Result += "\t"; 
6100   Result += llvm::utostr(flags); Result += ", "; 
6101   Result += InstanceStart; Result += ", ";
6102   Result += InstanceSize; Result += ", \n";
6103   Result += "\t";
6104   const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
6105   if (Triple.getArch() == llvm::Triple::x86_64)
6106     // uint32_t const reserved; // only when building for 64bit targets
6107     Result += "(unsigned int)0, \n\t";
6108   // const uint8_t * const ivarLayout;
6109   Result += "0, \n\t";
6110   Result += "\""; Result += ClassName; Result += "\",\n\t";
6111   bool metaclass = ((flags & CLS_META) != 0);
6112   if (baseMethods.size() > 0) {
6113     Result += "(const struct _method_list_t *)&";
6114     if (metaclass)
6115       Result += "_OBJC_$_CLASS_METHODS_";
6116     else
6117       Result += "_OBJC_$_INSTANCE_METHODS_";
6118     Result += ClassName;
6119     Result += ",\n\t";
6120   }
6121   else
6122     Result += "0, \n\t";
6123
6124   if (!metaclass && baseProtocols.size() > 0) {
6125     Result += "(const struct _objc_protocol_list *)&";
6126     Result += "_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6127     Result += ",\n\t";
6128   }
6129   else
6130     Result += "0, \n\t";
6131
6132   if (!metaclass && ivars.size() > 0) {
6133     Result += "(const struct _ivar_list_t *)&";
6134     Result += "_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6135     Result += ",\n\t";
6136   }
6137   else
6138     Result += "0, \n\t";
6139
6140   // weakIvarLayout
6141   Result += "0, \n\t";
6142   if (!metaclass && Properties.size() > 0) {
6143     Result += "(const struct _prop_list_t *)&";
6144     Result += "_OBJC_$_PROP_LIST_"; Result += ClassName;
6145     Result += ",\n";
6146   }
6147   else
6148     Result += "0, \n";
6149
6150   Result += "};\n";
6151 }
6152
6153 static void Write_class_t(ASTContext *Context, std::string &Result,
6154                           StringRef VarName,
6155                           const ObjCInterfaceDecl *CDecl, bool metaclass) {
6156   bool rootClass = (!CDecl->getSuperClass());
6157   const ObjCInterfaceDecl *RootClass = CDecl;
6158   
6159   if (!rootClass) {
6160     // Find the Root class
6161     RootClass = CDecl->getSuperClass();
6162     while (RootClass->getSuperClass()) {
6163       RootClass = RootClass->getSuperClass();
6164     }
6165   }
6166
6167   if (metaclass && rootClass) {
6168     // Need to handle a case of use of forward declaration.
6169     Result += "\n";
6170     Result += "extern \"C\" ";
6171     if (CDecl->getImplementation())
6172       Result += "__declspec(dllexport) ";
6173     else
6174       Result += "__declspec(dllimport) ";
6175     
6176     Result += "struct _class_t OBJC_CLASS_$_";
6177     Result += CDecl->getNameAsString();
6178     Result += ";\n";
6179   }
6180   // Also, for possibility of 'super' metadata class not having been defined yet.
6181   if (!rootClass) {
6182     ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
6183     Result += "\n";
6184     Result += "extern \"C\" ";
6185     if (SuperClass->getImplementation())
6186       Result += "__declspec(dllexport) ";
6187     else
6188       Result += "__declspec(dllimport) ";
6189
6190     Result += "struct _class_t "; 
6191     Result += VarName;
6192     Result += SuperClass->getNameAsString();
6193     Result += ";\n";
6194     
6195     if (metaclass && RootClass != SuperClass) {
6196       Result += "extern \"C\" ";
6197       if (RootClass->getImplementation())
6198         Result += "__declspec(dllexport) ";
6199       else
6200         Result += "__declspec(dllimport) ";
6201
6202       Result += "struct _class_t "; 
6203       Result += VarName;
6204       Result += RootClass->getNameAsString();
6205       Result += ";\n";
6206     }
6207   }
6208   
6209   Result += "\nextern \"C\" __declspec(dllexport) struct _class_t "; 
6210   Result += VarName; Result += CDecl->getNameAsString();
6211   Result += " __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6212   Result += "\t";
6213   if (metaclass) {
6214     if (!rootClass) {
6215       Result += "0, // &"; Result += VarName;
6216       Result += RootClass->getNameAsString();
6217       Result += ",\n\t";
6218       Result += "0, // &"; Result += VarName;
6219       Result += CDecl->getSuperClass()->getNameAsString();
6220       Result += ",\n\t";
6221     }
6222     else {
6223       Result += "0, // &"; Result += VarName; 
6224       Result += CDecl->getNameAsString();
6225       Result += ",\n\t";
6226       Result += "0, // &OBJC_CLASS_$_"; Result += CDecl->getNameAsString();
6227       Result += ",\n\t";
6228     }
6229   }
6230   else {
6231     Result += "0, // &OBJC_METACLASS_$_"; 
6232     Result += CDecl->getNameAsString();
6233     Result += ",\n\t";
6234     if (!rootClass) {
6235       Result += "0, // &"; Result += VarName;
6236       Result += CDecl->getSuperClass()->getNameAsString();
6237       Result += ",\n\t";
6238     }
6239     else 
6240       Result += "0,\n\t";
6241   }
6242   Result += "0, // (void *)&_objc_empty_cache,\n\t";
6243   Result += "0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6244   if (metaclass)
6245     Result += "&_OBJC_METACLASS_RO_$_";
6246   else
6247     Result += "&_OBJC_CLASS_RO_$_";
6248   Result += CDecl->getNameAsString();
6249   Result += ",\n};\n";
6250   
6251   // Add static function to initialize some of the meta-data fields.
6252   // avoid doing it twice.
6253   if (metaclass)
6254     return;
6255   
6256   const ObjCInterfaceDecl *SuperClass = 
6257     rootClass ? CDecl : CDecl->getSuperClass();
6258   
6259   Result += "static void OBJC_CLASS_SETUP_$_";
6260   Result += CDecl->getNameAsString();
6261   Result += "(void ) {\n";
6262   Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
6263   Result += ".isa = "; Result += "&OBJC_METACLASS_$_";
6264   Result += RootClass->getNameAsString(); Result += ";\n";
6265   
6266   Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
6267   Result += ".superclass = ";
6268   if (rootClass)
6269     Result += "&OBJC_CLASS_$_";
6270   else
6271      Result += "&OBJC_METACLASS_$_";
6272
6273   Result += SuperClass->getNameAsString(); Result += ";\n";
6274   
6275   Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
6276   Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n";
6277   
6278   Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
6279   Result += ".isa = "; Result += "&OBJC_METACLASS_$_";
6280   Result += CDecl->getNameAsString(); Result += ";\n";
6281   
6282   if (!rootClass) {
6283     Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
6284     Result += ".superclass = "; Result += "&OBJC_CLASS_$_";
6285     Result += SuperClass->getNameAsString(); Result += ";\n";
6286   }
6287   
6288   Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
6289   Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n";
6290   Result += "}\n";
6291 }
6292
6293 static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, 
6294                              std::string &Result,
6295                              ObjCCategoryDecl *CatDecl,
6296                              ObjCInterfaceDecl *ClassDecl,
6297                              ArrayRef<ObjCMethodDecl *> InstanceMethods,
6298                              ArrayRef<ObjCMethodDecl *> ClassMethods,
6299                              ArrayRef<ObjCProtocolDecl *> RefedProtocols,
6300                              ArrayRef<ObjCPropertyDecl *> ClassProperties) {
6301   StringRef CatName = CatDecl->getName();
6302   StringRef ClassName = ClassDecl->getName();
6303   // must declare an extern class object in case this class is not implemented 
6304   // in this TU.
6305   Result += "\n";
6306   Result += "extern \"C\" ";
6307   if (ClassDecl->getImplementation())
6308     Result += "__declspec(dllexport) ";
6309   else
6310     Result += "__declspec(dllimport) ";
6311   
6312   Result += "struct _class_t ";
6313   Result += "OBJC_CLASS_$_"; Result += ClassName;
6314   Result += ";\n";
6315   
6316   Result += "\nstatic struct _category_t ";
6317   Result += "_OBJC_$_CATEGORY_";
6318   Result += ClassName; Result += "_$_"; Result += CatName;
6319   Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6320   Result += "{\n";
6321   Result += "\t\""; Result += ClassName; Result += "\",\n";
6322   Result += "\t0, // &"; Result += "OBJC_CLASS_$_"; Result += ClassName;
6323   Result += ",\n";
6324   if (InstanceMethods.size() > 0) {
6325     Result += "\t(const struct _method_list_t *)&";  
6326     Result += "_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6327     Result += ClassName; Result += "_$_"; Result += CatName;
6328     Result += ",\n";
6329   }
6330   else
6331     Result += "\t0,\n";
6332   
6333   if (ClassMethods.size() > 0) {
6334     Result += "\t(const struct _method_list_t *)&";  
6335     Result += "_OBJC_$_CATEGORY_CLASS_METHODS_";
6336     Result += ClassName; Result += "_$_"; Result += CatName;
6337     Result += ",\n";
6338   }
6339   else
6340     Result += "\t0,\n";
6341   
6342   if (RefedProtocols.size() > 0) {
6343     Result += "\t(const struct _protocol_list_t *)&";  
6344     Result += "_OBJC_CATEGORY_PROTOCOLS_$_";
6345     Result += ClassName; Result += "_$_"; Result += CatName;
6346     Result += ",\n";
6347   }
6348   else
6349     Result += "\t0,\n";
6350   
6351   if (ClassProperties.size() > 0) {
6352     Result += "\t(const struct _prop_list_t *)&";  Result += "_OBJC_$_PROP_LIST_";
6353     Result += ClassName; Result += "_$_"; Result += CatName;
6354     Result += ",\n";
6355   }
6356   else
6357     Result += "\t0,\n";
6358   
6359   Result += "};\n";
6360   
6361   // Add static function to initialize the class pointer in the category structure.
6362   Result += "static void OBJC_CATEGORY_SETUP_$_";
6363   Result += ClassDecl->getNameAsString();
6364   Result += "_$_";
6365   Result += CatName;
6366   Result += "(void ) {\n";
6367   Result += "\t_OBJC_$_CATEGORY_"; 
6368   Result += ClassDecl->getNameAsString();
6369   Result += "_$_";
6370   Result += CatName;
6371   Result += ".cls = "; Result += "&OBJC_CLASS_$_"; Result += ClassName;
6372   Result += ";\n}\n";
6373 }
6374
6375 static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
6376                                            ASTContext *Context, std::string &Result,
6377                                            ArrayRef<ObjCMethodDecl *> Methods,
6378                                            StringRef VarName,
6379                                            StringRef ProtocolName) {
6380   if (Methods.size() == 0)
6381     return;
6382   
6383   Result += "\nstatic const char *";
6384   Result += VarName; Result += ProtocolName;
6385   Result += " [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6386   Result += "{\n";
6387   for (unsigned i = 0, e = Methods.size(); i < e; i++) {
6388     ObjCMethodDecl *MD = Methods[i];
6389     std::string MethodTypeString, QuoteMethodTypeString;
6390     Context->getObjCEncodingForMethodDecl(MD, MethodTypeString, true);
6391     RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6392     Result += "\t\""; Result += QuoteMethodTypeString; Result += "\"";
6393     if (i == e-1)
6394       Result += "\n};\n";
6395     else {
6396       Result += ",\n";
6397     }
6398   }
6399 }
6400
6401 static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
6402                                 ASTContext *Context,
6403                                 std::string &Result, 
6404                                 ArrayRef<ObjCIvarDecl *> Ivars, 
6405                                 ObjCInterfaceDecl *CDecl) {
6406   // FIXME. visibilty of offset symbols may have to be set; for Darwin
6407   // this is what happens:
6408   /**
6409    if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6410        Ivar->getAccessControl() == ObjCIvarDecl::Package ||
6411        Class->getVisibility() == HiddenVisibility)
6412      Visibility shoud be: HiddenVisibility;
6413    else
6414      Visibility shoud be: DefaultVisibility;
6415   */
6416   
6417   Result += "\n";
6418   for (unsigned i =0, e = Ivars.size(); i < e; i++) {
6419     ObjCIvarDecl *IvarDecl = Ivars[i];
6420     if (Context->getLangOpts().MicrosoftExt)
6421       Result += "__declspec(allocate(\".objc_ivar$B\")) ";
6422     
6423     if (!Context->getLangOpts().MicrosoftExt ||
6424         IvarDecl->getAccessControl() == ObjCIvarDecl::Private ||
6425         IvarDecl->getAccessControl() == ObjCIvarDecl::Package)
6426       Result += "extern \"C\" unsigned long int "; 
6427     else
6428       Result += "extern \"C\" __declspec(dllexport) unsigned long int ";
6429     WriteInternalIvarName(CDecl, IvarDecl, Result);
6430     Result += " __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6431     Result += " = ";
6432     RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6433     Result += ";\n";
6434   }
6435 }
6436
6437 static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
6438                                            ASTContext *Context, std::string &Result,
6439                                            ArrayRef<ObjCIvarDecl *> Ivars,
6440                                            StringRef VarName,
6441                                            ObjCInterfaceDecl *CDecl) {
6442   if (Ivars.size() > 0) {
6443     Write_IvarOffsetVar(RewriteObj, Context, Result, Ivars, CDecl);
6444     
6445     Result += "\nstatic ";
6446     Write__ivar_list_t_TypeDecl(Result, Ivars.size());
6447     Result += " "; Result += VarName;
6448     Result += CDecl->getNameAsString();
6449     Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6450     Result += "\t"; Result += "sizeof(_ivar_t)"; Result += ",\n";
6451     Result += "\t"; Result += utostr(Ivars.size()); Result += ",\n";
6452     for (unsigned i =0, e = Ivars.size(); i < e; i++) {
6453       ObjCIvarDecl *IvarDecl = Ivars[i];
6454       if (i == 0)
6455         Result += "\t{{";
6456       else
6457         Result += "\t {";
6458       Result += "(unsigned long int *)&";
6459       WriteInternalIvarName(CDecl, IvarDecl, Result);
6460       Result += ", ";
6461       
6462       Result += "\""; Result += IvarDecl->getName(); Result += "\", ";
6463       std::string IvarTypeString, QuoteIvarTypeString;
6464       Context->getObjCEncodingForType(IvarDecl->getType(), IvarTypeString,
6465                                       IvarDecl);
6466       RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6467       Result += "\""; Result += QuoteIvarTypeString; Result += "\", ";
6468       
6469       // FIXME. this alignment represents the host alignment and need be changed to
6470       // represent the target alignment.
6471       unsigned Align = Context->getTypeAlign(IvarDecl->getType())/8;
6472       Align = llvm::Log2_32(Align);
6473       Result += llvm::utostr(Align); Result += ", ";
6474       CharUnits Size = Context->getTypeSizeInChars(IvarDecl->getType());
6475       Result += llvm::utostr(Size.getQuantity());
6476       if (i  == e-1)
6477         Result += "}}\n";
6478       else
6479         Result += "},\n";
6480     }
6481     Result += "};\n";
6482   }
6483 }
6484
6485 /// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
6486 void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, 
6487                                                     std::string &Result) {
6488   
6489   // Do not synthesize the protocol more than once.
6490   if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl()))
6491     return;
6492   WriteModernMetadataDeclarations(Context, Result);
6493   
6494   if (ObjCProtocolDecl *Def = PDecl->getDefinition())
6495     PDecl = Def;
6496   // Must write out all protocol definitions in current qualifier list,
6497   // and in their nested qualifiers before writing out current definition.
6498   for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(),
6499        E = PDecl->protocol_end(); I != E; ++I)
6500     RewriteObjCProtocolMetaData(*I, Result);
6501   
6502   // Construct method lists.
6503   std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6504   std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6505   for (ObjCProtocolDecl::instmeth_iterator
6506        I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
6507        I != E; ++I) {
6508     ObjCMethodDecl *MD = *I;
6509     if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6510       OptInstanceMethods.push_back(MD);
6511     } else {
6512       InstanceMethods.push_back(MD);
6513     }
6514   }
6515   
6516   for (ObjCProtocolDecl::classmeth_iterator
6517        I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
6518        I != E; ++I) {
6519     ObjCMethodDecl *MD = *I;
6520     if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6521       OptClassMethods.push_back(MD);
6522     } else {
6523       ClassMethods.push_back(MD);
6524     }
6525   }
6526   std::vector<ObjCMethodDecl *> AllMethods;
6527   for (unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6528     AllMethods.push_back(InstanceMethods[i]);
6529   for (unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6530     AllMethods.push_back(ClassMethods[i]);
6531   for (unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6532     AllMethods.push_back(OptInstanceMethods[i]);
6533   for (unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6534     AllMethods.push_back(OptClassMethods[i]);
6535
6536   Write__extendedMethodTypes_initializer(*this, Context, Result,
6537                                          AllMethods,
6538                                          "_OBJC_PROTOCOL_METHOD_TYPES_",
6539                                          PDecl->getNameAsString());
6540   // Protocol's super protocol list
6541   std::vector<ObjCProtocolDecl *> SuperProtocols;
6542   for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(),
6543        E = PDecl->protocol_end(); I != E; ++I)
6544     SuperProtocols.push_back(*I);
6545   
6546   Write_protocol_list_initializer(Context, Result, SuperProtocols,
6547                                   "_OBJC_PROTOCOL_REFS_",
6548                                   PDecl->getNameAsString());
6549   
6550   Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 
6551                                   "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6552                                   PDecl->getNameAsString(), false);
6553   
6554   Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 
6555                                   "_OBJC_PROTOCOL_CLASS_METHODS_",
6556                                   PDecl->getNameAsString(), false);
6557
6558   Write_method_list_t_initializer(*this, Context, Result, OptInstanceMethods, 
6559                                   "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6560                                   PDecl->getNameAsString(), false);
6561   
6562   Write_method_list_t_initializer(*this, Context, Result, OptClassMethods, 
6563                                   "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6564                                   PDecl->getNameAsString(), false);
6565   
6566   // Protocol's property metadata.
6567   std::vector<ObjCPropertyDecl *> ProtocolProperties;
6568   for (ObjCContainerDecl::prop_iterator I = PDecl->prop_begin(),
6569        E = PDecl->prop_end(); I != E; ++I)
6570     ProtocolProperties.push_back(*I);
6571   
6572   Write_prop_list_t_initializer(*this, Context, Result, ProtocolProperties,
6573                                  /* Container */0,
6574                                  "_OBJC_PROTOCOL_PROPERTIES_",
6575                                  PDecl->getNameAsString());
6576   
6577   // Writer out root metadata for current protocol: struct _protocol_t
6578   Result += "\n";
6579   if (LangOpts.MicrosoftExt)
6580     Result += "static ";
6581   Result += "struct _protocol_t _OBJC_PROTOCOL_";
6582   Result += PDecl->getNameAsString();
6583   Result += " __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n";
6584   Result += "\t0,\n"; // id is; is null
6585   Result += "\t\""; Result += PDecl->getNameAsString(); Result += "\",\n";
6586   if (SuperProtocols.size() > 0) {
6587     Result += "\t(const struct _protocol_list_t *)&"; Result += "_OBJC_PROTOCOL_REFS_";
6588     Result += PDecl->getNameAsString(); Result += ",\n";
6589   }
6590   else
6591     Result += "\t0,\n";
6592   if (InstanceMethods.size() > 0) {
6593     Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 
6594     Result += PDecl->getNameAsString(); Result += ",\n";
6595   }
6596   else
6597     Result += "\t0,\n";
6598
6599   if (ClassMethods.size() > 0) {
6600     Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 
6601     Result += PDecl->getNameAsString(); Result += ",\n";
6602   }
6603   else
6604     Result += "\t0,\n";
6605   
6606   if (OptInstanceMethods.size() > 0) {
6607     Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_"; 
6608     Result += PDecl->getNameAsString(); Result += ",\n";
6609   }
6610   else
6611     Result += "\t0,\n";
6612   
6613   if (OptClassMethods.size() > 0) {
6614     Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_"; 
6615     Result += PDecl->getNameAsString(); Result += ",\n";
6616   }
6617   else
6618     Result += "\t0,\n";
6619   
6620   if (ProtocolProperties.size() > 0) {
6621     Result += "\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_"; 
6622     Result += PDecl->getNameAsString(); Result += ",\n";
6623   }
6624   else
6625     Result += "\t0,\n";
6626   
6627   Result += "\t"; Result += "sizeof(_protocol_t)"; Result += ",\n";
6628   Result += "\t0,\n";
6629   
6630   if (AllMethods.size() > 0) {
6631     Result += "\t(const char **)&"; Result += "_OBJC_PROTOCOL_METHOD_TYPES_";
6632     Result += PDecl->getNameAsString();
6633     Result += "\n};\n";
6634   }
6635   else
6636     Result += "\t0\n};\n";
6637   
6638   if (LangOpts.MicrosoftExt)
6639     Result += "static ";
6640   Result += "struct _protocol_t *";
6641   Result += "_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->getNameAsString();
6642   Result += " = &_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
6643   Result += ";\n";
6644     
6645   // Mark this protocol as having been generated.
6646   if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()))
6647     llvm_unreachable("protocol already synthesized");
6648   
6649 }
6650
6651 void RewriteModernObjC::RewriteObjCProtocolListMetaData(
6652                                 const ObjCList<ObjCProtocolDecl> &Protocols,
6653                                 StringRef prefix, StringRef ClassName,
6654                                 std::string &Result) {
6655   if (Protocols.empty()) return;
6656   
6657   for (unsigned i = 0; i != Protocols.size(); i++)
6658     RewriteObjCProtocolMetaData(Protocols[i], Result);
6659   
6660   // Output the top lovel protocol meta-data for the class.
6661   /* struct _objc_protocol_list {
6662    struct _objc_protocol_list *next;
6663    int    protocol_count;
6664    struct _objc_protocol *class_protocols[];
6665    }
6666    */
6667   Result += "\n";
6668   if (LangOpts.MicrosoftExt)
6669     Result += "__declspec(allocate(\".cat_cls_meth$B\")) ";
6670   Result += "static struct {\n";
6671   Result += "\tstruct _objc_protocol_list *next;\n";
6672   Result += "\tint    protocol_count;\n";
6673   Result += "\tstruct _objc_protocol *class_protocols[";
6674   Result += utostr(Protocols.size());
6675   Result += "];\n} _OBJC_";
6676   Result += prefix;
6677   Result += "_PROTOCOLS_";
6678   Result += ClassName;
6679   Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
6680   "{\n\t0, ";
6681   Result += utostr(Protocols.size());
6682   Result += "\n";
6683   
6684   Result += "\t,{&_OBJC_PROTOCOL_";
6685   Result += Protocols[0]->getNameAsString();
6686   Result += " \n";
6687   
6688   for (unsigned i = 1; i != Protocols.size(); i++) {
6689     Result += "\t ,&_OBJC_PROTOCOL_";
6690     Result += Protocols[i]->getNameAsString();
6691     Result += "\n";
6692   }
6693   Result += "\t }\n};\n";
6694 }
6695
6696 /// hasObjCExceptionAttribute - Return true if this class or any super
6697 /// class has the __objc_exception__ attribute.
6698 /// FIXME. Move this to ASTContext.cpp as it is also used for IRGen.
6699 static bool hasObjCExceptionAttribute(ASTContext &Context,
6700                                       const ObjCInterfaceDecl *OID) {
6701   if (OID->hasAttr<ObjCExceptionAttr>())
6702     return true;
6703   if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
6704     return hasObjCExceptionAttribute(Context, Super);
6705   return false;
6706 }
6707
6708 void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
6709                                            std::string &Result) {
6710   ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
6711   
6712   // Explicitly declared @interface's are already synthesized.
6713   if (CDecl->isImplicitInterfaceDecl())
6714     assert(false && 
6715            "Legacy implicit interface rewriting not supported in moder abi");
6716   
6717   WriteModernMetadataDeclarations(Context, Result);
6718   SmallVector<ObjCIvarDecl *, 8> IVars;
6719   
6720   for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
6721       IVD; IVD = IVD->getNextIvar()) {
6722     // Ignore unnamed bit-fields.
6723     if (!IVD->getDeclName())
6724       continue;
6725     IVars.push_back(IVD);
6726   }
6727   
6728   Write__ivar_list_t_initializer(*this, Context, Result, IVars, 
6729                                  "_OBJC_$_INSTANCE_VARIABLES_",
6730                                  CDecl);
6731   
6732   // Build _objc_method_list for class's instance methods if needed
6733   SmallVector<ObjCMethodDecl *, 32>
6734     InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
6735   
6736   // If any of our property implementations have associated getters or
6737   // setters, produce metadata for them as well.
6738   for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
6739        PropEnd = IDecl->propimpl_end();
6740        Prop != PropEnd; ++Prop) {
6741     if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
6742       continue;
6743     if (!(*Prop)->getPropertyIvarDecl())
6744       continue;
6745     ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
6746     if (!PD)
6747       continue;
6748     if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
6749       if (!Getter->isDefined())
6750         InstanceMethods.push_back(Getter);
6751     if (PD->isReadOnly())
6752       continue;
6753     if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
6754       if (!Setter->isDefined())
6755         InstanceMethods.push_back(Setter);
6756   }
6757   
6758   Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
6759                                   "_OBJC_$_INSTANCE_METHODS_",
6760                                   IDecl->getNameAsString(), true);
6761   
6762   SmallVector<ObjCMethodDecl *, 32>
6763     ClassMethods(IDecl->classmeth_begin(), IDecl->classmeth_end());
6764   
6765   Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
6766                                   "_OBJC_$_CLASS_METHODS_",
6767                                   IDecl->getNameAsString(), true);
6768   
6769   // Protocols referenced in class declaration?
6770   // Protocol's super protocol list
6771   std::vector<ObjCProtocolDecl *> RefedProtocols;
6772   const ObjCList<ObjCProtocolDecl> &Protocols = CDecl->getReferencedProtocols();
6773   for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6774        E = Protocols.end();
6775        I != E; ++I) {
6776     RefedProtocols.push_back(*I);
6777     // Must write out all protocol definitions in current qualifier list,
6778     // and in their nested qualifiers before writing out current definition.
6779     RewriteObjCProtocolMetaData(*I, Result);
6780   }
6781   
6782   Write_protocol_list_initializer(Context, Result, 
6783                                   RefedProtocols,
6784                                   "_OBJC_CLASS_PROTOCOLS_$_",
6785                                   IDecl->getNameAsString());
6786   
6787   // Protocol's property metadata.
6788   std::vector<ObjCPropertyDecl *> ClassProperties;
6789   for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
6790        E = CDecl->prop_end(); I != E; ++I)
6791     ClassProperties.push_back(*I);
6792   
6793   Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
6794                                  /* Container */IDecl,
6795                                  "_OBJC_$_PROP_LIST_",
6796                                  CDecl->getNameAsString());
6797
6798   
6799   // Data for initializing _class_ro_t  metaclass meta-data
6800   uint32_t flags = CLS_META;
6801   std::string InstanceSize;
6802   std::string InstanceStart;
6803   
6804   
6805   bool classIsHidden = CDecl->getVisibility() == HiddenVisibility;
6806   if (classIsHidden)
6807     flags |= OBJC2_CLS_HIDDEN;
6808   
6809   if (!CDecl->getSuperClass())
6810     // class is root
6811     flags |= CLS_ROOT;
6812   InstanceSize = "sizeof(struct _class_t)";
6813   InstanceStart = InstanceSize;
6814   Write__class_ro_t_initializer(Context, Result, flags, 
6815                                 InstanceStart, InstanceSize,
6816                                 ClassMethods,
6817                                 0,
6818                                 0,
6819                                 0,
6820                                 "_OBJC_METACLASS_RO_$_",
6821                                 CDecl->getNameAsString());
6822
6823   
6824   // Data for initializing _class_ro_t meta-data
6825   flags = CLS;
6826   if (classIsHidden)
6827     flags |= OBJC2_CLS_HIDDEN;
6828   
6829   if (hasObjCExceptionAttribute(*Context, CDecl))
6830     flags |= CLS_EXCEPTION;
6831
6832   if (!CDecl->getSuperClass())
6833     // class is root
6834     flags |= CLS_ROOT;
6835   
6836   InstanceSize.clear();
6837   InstanceStart.clear();
6838   if (!ObjCSynthesizedStructs.count(CDecl)) {
6839     InstanceSize = "0";
6840     InstanceStart = "0";
6841   }
6842   else {
6843     InstanceSize = "sizeof(struct ";
6844     InstanceSize += CDecl->getNameAsString();
6845     InstanceSize += "_IMPL)";
6846     
6847     ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
6848     if (IVD) {
6849       RewriteIvarOffsetComputation(IVD, InstanceStart);
6850     }
6851     else 
6852       InstanceStart = InstanceSize;
6853   }
6854   Write__class_ro_t_initializer(Context, Result, flags, 
6855                                 InstanceStart, InstanceSize,
6856                                 InstanceMethods,
6857                                 RefedProtocols,
6858                                 IVars,
6859                                 ClassProperties,
6860                                 "_OBJC_CLASS_RO_$_",
6861                                 CDecl->getNameAsString());
6862   
6863   Write_class_t(Context, Result,
6864                 "OBJC_METACLASS_$_",
6865                 CDecl, /*metaclass*/true);
6866   
6867   Write_class_t(Context, Result,
6868                 "OBJC_CLASS_$_",
6869                 CDecl, /*metaclass*/false);
6870   
6871   if (ImplementationIsNonLazy(IDecl))
6872     DefinedNonLazyClasses.push_back(CDecl);
6873                 
6874 }
6875
6876 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
6877   int ClsDefCount = ClassImplementation.size();
6878   if (!ClsDefCount)
6879     return;
6880   Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n";
6881   Result += "__declspec(allocate(\".objc_inithooks$B\")) ";
6882   Result += "static void *OBJC_CLASS_SETUP[] = {\n";
6883   for (int i = 0; i < ClsDefCount; i++) {
6884     ObjCImplementationDecl *IDecl = ClassImplementation[i];
6885     ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
6886     Result += "\t(void *)&OBJC_CLASS_SETUP_$_";
6887     Result  += CDecl->getName(); Result += ",\n";
6888   }
6889   Result += "};\n";
6890 }
6891
6892 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
6893   int ClsDefCount = ClassImplementation.size();
6894   int CatDefCount = CategoryImplementation.size();
6895   
6896   // For each implemented class, write out all its meta data.
6897   for (int i = 0; i < ClsDefCount; i++)
6898     RewriteObjCClassMetaData(ClassImplementation[i], Result);
6899   
6900   RewriteClassSetupInitHook(Result);
6901   
6902   // For each implemented category, write out all its meta data.
6903   for (int i = 0; i < CatDefCount; i++)
6904     RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
6905   
6906   RewriteCategorySetupInitHook(Result);
6907   
6908   if (ClsDefCount > 0) {
6909     if (LangOpts.MicrosoftExt)
6910       Result += "__declspec(allocate(\".objc_classlist$B\")) ";
6911     Result += "static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
6912     Result += llvm::utostr(ClsDefCount); Result += "]";
6913     Result += 
6914       " __attribute__((used, section (\"__DATA, __objc_classlist,"
6915       "regular,no_dead_strip\")))= {\n";
6916     for (int i = 0; i < ClsDefCount; i++) {
6917       Result += "\t&OBJC_CLASS_$_";
6918       Result += ClassImplementation[i]->getNameAsString();
6919       Result += ",\n";
6920     }
6921     Result += "};\n";
6922     
6923     if (!DefinedNonLazyClasses.empty()) {
6924       if (LangOpts.MicrosoftExt)
6925         Result += "__declspec(allocate(\".objc_nlclslist$B\")) \n";
6926       Result += "static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
6927       for (unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
6928         Result += "\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
6929         Result += ",\n";
6930       }
6931       Result += "};\n";
6932     }
6933   }
6934   
6935   if (CatDefCount > 0) {
6936     if (LangOpts.MicrosoftExt)
6937       Result += "__declspec(allocate(\".objc_catlist$B\")) ";
6938     Result += "static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
6939     Result += llvm::utostr(CatDefCount); Result += "]";
6940     Result += 
6941     " __attribute__((used, section (\"__DATA, __objc_catlist,"
6942     "regular,no_dead_strip\")))= {\n";
6943     for (int i = 0; i < CatDefCount; i++) {
6944       Result += "\t&_OBJC_$_CATEGORY_";
6945       Result += 
6946         CategoryImplementation[i]->getClassInterface()->getNameAsString(); 
6947       Result += "_$_";
6948       Result += CategoryImplementation[i]->getNameAsString();
6949       Result += ",\n";
6950     }
6951     Result += "};\n";
6952   }
6953   
6954   if (!DefinedNonLazyCategories.empty()) {
6955     if (LangOpts.MicrosoftExt)
6956       Result += "__declspec(allocate(\".objc_nlcatlist$B\")) \n";
6957     Result += "static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
6958     for (unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
6959       Result += "\t&_OBJC_$_CATEGORY_";
6960       Result += 
6961         DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString(); 
6962       Result += "_$_";
6963       Result += DefinedNonLazyCategories[i]->getNameAsString();
6964       Result += ",\n";
6965     }
6966     Result += "};\n";
6967   }
6968 }
6969
6970 void RewriteModernObjC::WriteImageInfo(std::string &Result) {
6971   if (LangOpts.MicrosoftExt)
6972     Result += "__declspec(allocate(\".objc_imageinfo$B\")) \n";
6973   
6974   Result += "static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
6975   // version 0, ObjCABI is 2
6976   Result += "_OBJC_IMAGE_INFO = { 0, 2 };\n";
6977 }
6978
6979 /// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
6980 /// implementation.
6981 void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
6982                                               std::string &Result) {
6983   WriteModernMetadataDeclarations(Context, Result);
6984   ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
6985   // Find category declaration for this implementation.
6986   ObjCCategoryDecl *CDecl=0;
6987   for (CDecl = ClassDecl->getCategoryList(); CDecl;
6988        CDecl = CDecl->getNextClassCategory())
6989     if (CDecl->getIdentifier() == IDecl->getIdentifier())
6990       break;
6991   
6992   std::string FullCategoryName = ClassDecl->getNameAsString();
6993   FullCategoryName += "_$_";
6994   FullCategoryName += CDecl->getNameAsString();
6995   
6996   // Build _objc_method_list for class's instance methods if needed
6997   SmallVector<ObjCMethodDecl *, 32>
6998   InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
6999   
7000   // If any of our property implementations have associated getters or
7001   // setters, produce metadata for them as well.
7002   for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
7003        PropEnd = IDecl->propimpl_end();
7004        Prop != PropEnd; ++Prop) {
7005     if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7006       continue;
7007     if (!(*Prop)->getPropertyIvarDecl())
7008       continue;
7009     ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
7010     if (!PD)
7011       continue;
7012     if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
7013       InstanceMethods.push_back(Getter);
7014     if (PD->isReadOnly())
7015       continue;
7016     if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
7017       InstanceMethods.push_back(Setter);
7018   }
7019   
7020   Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
7021                                   "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7022                                   FullCategoryName, true);
7023   
7024   SmallVector<ObjCMethodDecl *, 32>
7025     ClassMethods(IDecl->classmeth_begin(), IDecl->classmeth_end());
7026   
7027   Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
7028                                   "_OBJC_$_CATEGORY_CLASS_METHODS_",
7029                                   FullCategoryName, true);
7030   
7031   // Protocols referenced in class declaration?
7032   // Protocol's super protocol list
7033   std::vector<ObjCProtocolDecl *> RefedProtocols;
7034   for (ObjCInterfaceDecl::protocol_iterator I = CDecl->protocol_begin(),
7035                                             E = CDecl->protocol_end();
7036
7037          I != E; ++I) {
7038     RefedProtocols.push_back(*I);
7039     // Must write out all protocol definitions in current qualifier list,
7040     // and in their nested qualifiers before writing out current definition.
7041     RewriteObjCProtocolMetaData(*I, Result);
7042   }
7043   
7044   Write_protocol_list_initializer(Context, Result, 
7045                                   RefedProtocols,
7046                                   "_OBJC_CATEGORY_PROTOCOLS_$_",
7047                                   FullCategoryName);
7048   
7049   // Protocol's property metadata.
7050   std::vector<ObjCPropertyDecl *> ClassProperties;
7051   for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
7052        E = CDecl->prop_end(); I != E; ++I)
7053     ClassProperties.push_back(*I);
7054   
7055   Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
7056                                 /* Container */0,
7057                                 "_OBJC_$_PROP_LIST_",
7058                                 FullCategoryName);
7059   
7060   Write_category_t(*this, Context, Result,
7061                    CDecl,
7062                    ClassDecl,
7063                    InstanceMethods,
7064                    ClassMethods,
7065                    RefedProtocols,
7066                    ClassProperties);
7067   
7068   // Determine if this category is also "non-lazy".
7069   if (ImplementationIsNonLazy(IDecl))
7070     DefinedNonLazyCategories.push_back(CDecl);
7071     
7072 }
7073
7074 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7075   int CatDefCount = CategoryImplementation.size();
7076   if (!CatDefCount)
7077     return;
7078   Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7079   Result += "__declspec(allocate(\".objc_inithooks$B\")) ";
7080   Result += "static void *OBJC_CATEGORY_SETUP[] = {\n";
7081   for (int i = 0; i < CatDefCount; i++) {
7082     ObjCCategoryImplDecl *IDecl = CategoryImplementation[i];
7083     ObjCCategoryDecl *CatDecl= IDecl->getCategoryDecl();
7084     ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
7085     Result += "\t(void *)&OBJC_CATEGORY_SETUP_$_";
7086     Result += ClassDecl->getName();
7087     Result += "_$_";
7088     Result += CatDecl->getName();
7089     Result += ",\n";
7090   }
7091   Result += "};\n";
7092 }
7093
7094 // RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
7095 /// class methods.
7096 template<typename MethodIterator>
7097 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7098                                              MethodIterator MethodEnd,
7099                                              bool IsInstanceMethod,
7100                                              StringRef prefix,
7101                                              StringRef ClassName,
7102                                              std::string &Result) {
7103   if (MethodBegin == MethodEnd) return;
7104   
7105   if (!objc_impl_method) {
7106     /* struct _objc_method {
7107      SEL _cmd;
7108      char *method_types;
7109      void *_imp;
7110      }
7111      */
7112     Result += "\nstruct _objc_method {\n";
7113     Result += "\tSEL _cmd;\n";
7114     Result += "\tchar *method_types;\n";
7115     Result += "\tvoid *_imp;\n";
7116     Result += "};\n";
7117     
7118     objc_impl_method = true;
7119   }
7120   
7121   // Build _objc_method_list for class's methods if needed
7122   
7123   /* struct  {
7124    struct _objc_method_list *next_method;
7125    int method_count;
7126    struct _objc_method method_list[];
7127    }
7128    */
7129   unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
7130   Result += "\n";
7131   if (LangOpts.MicrosoftExt) {
7132     if (IsInstanceMethod)
7133       Result += "__declspec(allocate(\".inst_meth$B\")) ";
7134     else
7135       Result += "__declspec(allocate(\".cls_meth$B\")) ";
7136   }
7137   Result += "static struct {\n";
7138   Result += "\tstruct _objc_method_list *next_method;\n";
7139   Result += "\tint method_count;\n";
7140   Result += "\tstruct _objc_method method_list[";
7141   Result += utostr(NumMethods);
7142   Result += "];\n} _OBJC_";
7143   Result += prefix;
7144   Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
7145   Result += "_METHODS_";
7146   Result += ClassName;
7147   Result += " __attribute__ ((used, section (\"__OBJC, __";
7148   Result += IsInstanceMethod ? "inst" : "cls";
7149   Result += "_meth\")))= ";
7150   Result += "{\n\t0, " + utostr(NumMethods) + "\n";
7151   
7152   Result += "\t,{{(SEL)\"";
7153   Result += (*MethodBegin)->getSelector().getAsString().c_str();
7154   std::string MethodTypeString;
7155   Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7156   Result += "\", \"";
7157   Result += MethodTypeString;
7158   Result += "\", (void *)";
7159   Result += MethodInternalNames[*MethodBegin];
7160   Result += "}\n";
7161   for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7162     Result += "\t  ,{(SEL)\"";
7163     Result += (*MethodBegin)->getSelector().getAsString().c_str();
7164     std::string MethodTypeString;
7165     Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7166     Result += "\", \"";
7167     Result += MethodTypeString;
7168     Result += "\", (void *)";
7169     Result += MethodInternalNames[*MethodBegin];
7170     Result += "}\n";
7171   }
7172   Result += "\t }\n};\n";
7173 }
7174
7175 Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
7176   SourceRange OldRange = IV->getSourceRange();
7177   Expr *BaseExpr = IV->getBase();
7178   
7179   // Rewrite the base, but without actually doing replaces.
7180   {
7181     DisableReplaceStmtScope S(*this);
7182     BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7183     IV->setBase(BaseExpr);
7184   }
7185   
7186   ObjCIvarDecl *D = IV->getDecl();
7187   
7188   Expr *Replacement = IV;
7189   
7190     if (BaseExpr->getType()->isObjCObjectPointerType()) {
7191       const ObjCInterfaceType *iFaceDecl =
7192       dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
7193       assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
7194       // lookup which class implements the instance variable.
7195       ObjCInterfaceDecl *clsDeclared = 0;
7196       iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
7197                                                    clsDeclared);
7198       assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
7199       
7200       // Build name of symbol holding ivar offset.
7201       std::string IvarOffsetName;
7202       WriteInternalIvarName(clsDeclared, D, IvarOffsetName);
7203       
7204       ReferencedIvars[clsDeclared].insert(D);
7205       
7206       // cast offset to "char *".
7207       CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, 
7208                                                     Context->getPointerType(Context->CharTy),
7209                                                     CK_BitCast,
7210                                                     BaseExpr);
7211       VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
7212                                        SourceLocation(), &Context->Idents.get(IvarOffsetName),
7213                                        Context->UnsignedLongTy, 0, SC_Extern, SC_None);
7214       DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false,
7215                                                    Context->UnsignedLongTy, VK_LValue,
7216                                                    SourceLocation());
7217       BinaryOperator *addExpr = 
7218         new (Context) BinaryOperator(castExpr, DRE, BO_Add, 
7219                                      Context->getPointerType(Context->CharTy),
7220                                      VK_RValue, OK_Ordinary, SourceLocation());
7221       // Don't forget the parens to enforce the proper binding.
7222       ParenExpr *PE = new (Context) ParenExpr(SourceLocation(),
7223                                               SourceLocation(),
7224                                               addExpr);
7225       QualType IvarT = D->getType();
7226       convertObjCTypeToCStyleType(IvarT);
7227       QualType castT = Context->getPointerType(IvarT);
7228       
7229       castExpr = NoTypeInfoCStyleCastExpr(Context, 
7230                                           castT,
7231                                           CK_BitCast,
7232                                           PE);
7233       Expr *Exp = new (Context) UnaryOperator(castExpr, UO_Deref, IvarT,
7234                                               VK_LValue, OK_Ordinary,
7235                                               SourceLocation());
7236       PE = new (Context) ParenExpr(OldRange.getBegin(),
7237                                    OldRange.getEnd(),
7238                                    Exp);
7239
7240       Replacement = PE;
7241     }
7242   
7243     ReplaceStmtWithRange(IV, Replacement, OldRange);
7244     return Replacement;  
7245 }