ObjCMT.cpp revision 74fd551c0ba344d62aedc8636ed81b45652f04d8
1//===--- ObjCMT.cpp - ObjC Migrate Tool -----------------------------------===//
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#include "Transforms.h"
11#include "clang/ARCMigrate/ARCMTActions.h"
12#include "clang/AST/ASTConsumer.h"
13#include "clang/AST/ASTContext.h"
14#include "clang/AST/NSAPI.h"
15#include "clang/AST/ParentMap.h"
16#include "clang/AST/RecursiveASTVisitor.h"
17#include "clang/Basic/FileManager.h"
18#include "clang/Edit/Commit.h"
19#include "clang/Edit/EditedSource.h"
20#include "clang/Edit/EditsReceiver.h"
21#include "clang/Edit/Rewriters.h"
22#include "clang/Frontend/CompilerInstance.h"
23#include "clang/Frontend/MultiplexConsumer.h"
24#include "clang/Lex/PPConditionalDirectiveRecord.h"
25#include "clang/Lex/Preprocessor.h"
26#include "clang/Rewrite/Core/Rewriter.h"
27#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
28#include "clang/StaticAnalyzer/Checkers/ObjCRetainCount.h"
29#include "clang/AST/Attr.h"
30#include "llvm/ADT/SmallString.h"
31
32using namespace clang;
33using namespace arcmt;
34using namespace ento::objc_retain;
35
36namespace {
37
38class ObjCMigrateASTConsumer : public ASTConsumer {
39  enum CF_BRIDGING_KIND {
40    CF_BRIDGING_NONE,
41    CF_BRIDGING_ENABLE,
42    CF_BRIDGING_MAY_INCLUDE
43  };
44
45  void migrateDecl(Decl *D);
46  void migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCContainerDecl *D);
47  void migrateProtocolConformance(ASTContext &Ctx,
48                                  const ObjCImplementationDecl *ImpDecl);
49  void migrateNSEnumDecl(ASTContext &Ctx, const EnumDecl *EnumDcl,
50                     const TypedefDecl *TypedefDcl);
51  void migrateMethods(ASTContext &Ctx, ObjCContainerDecl *CDecl);
52  void migrateMethodInstanceType(ASTContext &Ctx, ObjCContainerDecl *CDecl,
53                                 ObjCMethodDecl *OM);
54  bool migrateProperty(ASTContext &Ctx, ObjCContainerDecl *D, ObjCMethodDecl *OM);
55  void migrateNsReturnsInnerPointer(ASTContext &Ctx, ObjCMethodDecl *OM);
56  void migratePropertyNsReturnsInnerPointer(ASTContext &Ctx, ObjCPropertyDecl *P);
57  void migrateFactoryMethod(ASTContext &Ctx, ObjCContainerDecl *CDecl,
58                            ObjCMethodDecl *OM,
59                            ObjCInstanceTypeFamily OIT_Family = OIT_None);
60
61  void migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl);
62  void AddCFAnnotations(ASTContext &Ctx, const CallEffects &CE,
63                        const FunctionDecl *FuncDecl, bool ResultAnnotated);
64  void AddCFAnnotations(ASTContext &Ctx, const CallEffects &CE,
65                        const ObjCMethodDecl *MethodDecl, bool ResultAnnotated);
66
67  void AnnotateImplicitBridging(ASTContext &Ctx);
68
69  CF_BRIDGING_KIND migrateAddFunctionAnnotation(ASTContext &Ctx,
70                                                const FunctionDecl *FuncDecl);
71
72  void migrateARCSafeAnnotation(ASTContext &Ctx, ObjCContainerDecl *CDecl);
73
74  void migrateAddMethodAnnotation(ASTContext &Ctx,
75                                  const ObjCMethodDecl *MethodDecl);
76public:
77  std::string MigrateDir;
78  unsigned ASTMigrateActions;
79  unsigned  FileId;
80  OwningPtr<NSAPI> NSAPIObj;
81  OwningPtr<edit::EditedSource> Editor;
82  FileRemapper &Remapper;
83  FileManager &FileMgr;
84  const PPConditionalDirectiveRecord *PPRec;
85  Preprocessor &PP;
86  bool IsOutputFile;
87  llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ObjCProtocolDecls;
88  llvm::SmallVector<const Decl *, 8> CFFunctionIBCandidates;
89
90  ObjCMigrateASTConsumer(StringRef migrateDir,
91                         unsigned astMigrateActions,
92                         FileRemapper &remapper,
93                         FileManager &fileMgr,
94                         const PPConditionalDirectiveRecord *PPRec,
95                         Preprocessor &PP,
96                         bool isOutputFile = false)
97  : MigrateDir(migrateDir),
98    ASTMigrateActions(astMigrateActions),
99    FileId(0), Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP),
100    IsOutputFile(isOutputFile) { }
101
102protected:
103  virtual void Initialize(ASTContext &Context) {
104    NSAPIObj.reset(new NSAPI(Context));
105    Editor.reset(new edit::EditedSource(Context.getSourceManager(),
106                                        Context.getLangOpts(),
107                                        PPRec, false));
108  }
109
110  virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
111    for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
112      migrateDecl(*I);
113    return true;
114  }
115  virtual void HandleInterestingDecl(DeclGroupRef DG) {
116    // Ignore decls from the PCH.
117  }
118  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) {
119    ObjCMigrateASTConsumer::HandleTopLevelDecl(DG);
120  }
121
122  virtual void HandleTranslationUnit(ASTContext &Ctx);
123};
124
125}
126
127ObjCMigrateAction::ObjCMigrateAction(FrontendAction *WrappedAction,
128                                     StringRef migrateDir,
129                                     unsigned migrateAction)
130  : WrapperFrontendAction(WrappedAction), MigrateDir(migrateDir),
131    ObjCMigAction(migrateAction),
132    CompInst(0) {
133  if (MigrateDir.empty())
134    MigrateDir = "."; // user current directory if none is given.
135}
136
137ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI,
138                                                  StringRef InFile) {
139  PPConditionalDirectiveRecord *
140    PPRec = new PPConditionalDirectiveRecord(CompInst->getSourceManager());
141  CompInst->getPreprocessor().addPPCallbacks(PPRec);
142  ASTConsumer *
143    WrappedConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
144  ASTConsumer *MTConsumer = new ObjCMigrateASTConsumer(MigrateDir,
145                                                       ObjCMigAction,
146                                                       Remapper,
147                                                    CompInst->getFileManager(),
148                                                       PPRec,
149                                                       CompInst->getPreprocessor());
150  ASTConsumer *Consumers[] = { MTConsumer, WrappedConsumer };
151  return new MultiplexConsumer(Consumers);
152}
153
154bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) {
155  Remapper.initFromDisk(MigrateDir, CI.getDiagnostics(),
156                        /*ignoreIfFilesChanges=*/true);
157  CompInst = &CI;
158  CI.getDiagnostics().setIgnoreAllWarnings(true);
159  return true;
160}
161
162namespace {
163class ObjCMigrator : public RecursiveASTVisitor<ObjCMigrator> {
164  ObjCMigrateASTConsumer &Consumer;
165  ParentMap &PMap;
166
167public:
168  ObjCMigrator(ObjCMigrateASTConsumer &consumer, ParentMap &PMap)
169    : Consumer(consumer), PMap(PMap) { }
170
171  bool shouldVisitTemplateInstantiations() const { return false; }
172  bool shouldWalkTypesOfTypeLocs() const { return false; }
173
174  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
175    if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Literals) {
176      edit::Commit commit(*Consumer.Editor);
177      edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit, &PMap);
178      Consumer.Editor->commit(commit);
179    }
180
181    if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Subscripting) {
182      edit::Commit commit(*Consumer.Editor);
183      edit::rewriteToObjCSubscriptSyntax(E, *Consumer.NSAPIObj, commit);
184      Consumer.Editor->commit(commit);
185    }
186
187    return true;
188  }
189
190  bool TraverseObjCMessageExpr(ObjCMessageExpr *E) {
191    // Do depth first; we want to rewrite the subexpressions first so that if
192    // we have to move expressions we will move them already rewritten.
193    for (Stmt::child_range range = E->children(); range; ++range)
194      if (!TraverseStmt(*range))
195        return false;
196
197    return WalkUpFromObjCMessageExpr(E);
198  }
199};
200
201class BodyMigrator : public RecursiveASTVisitor<BodyMigrator> {
202  ObjCMigrateASTConsumer &Consumer;
203  OwningPtr<ParentMap> PMap;
204
205public:
206  BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { }
207
208  bool shouldVisitTemplateInstantiations() const { return false; }
209  bool shouldWalkTypesOfTypeLocs() const { return false; }
210
211  bool TraverseStmt(Stmt *S) {
212    PMap.reset(new ParentMap(S));
213    ObjCMigrator(Consumer, *PMap).TraverseStmt(S);
214    return true;
215  }
216};
217}
218
219void ObjCMigrateASTConsumer::migrateDecl(Decl *D) {
220  if (!D)
221    return;
222  if (isa<ObjCMethodDecl>(D))
223    return; // Wait for the ObjC container declaration.
224
225  BodyMigrator(*this).TraverseDecl(D);
226}
227
228static void append_attr(std::string &PropertyString, const char *attr) {
229  PropertyString += ", ";
230  PropertyString += attr;
231}
232
233static bool rewriteToObjCProperty(const ObjCMethodDecl *Getter,
234                                  const ObjCMethodDecl *Setter,
235                                  const NSAPI &NS, edit::Commit &commit,
236                                  unsigned LengthOfPrefix) {
237  ASTContext &Context = NS.getASTContext();
238  std::string PropertyString = "@property (nonatomic";
239  std::string PropertyNameString = Getter->getNameAsString();
240  StringRef PropertyName(PropertyNameString);
241  if (LengthOfPrefix > 0) {
242    PropertyString += ", getter=";
243    PropertyString += PropertyNameString;
244  }
245  // Property with no setter may be suggested as a 'readonly' property.
246  if (!Setter)
247    append_attr(PropertyString, "readonly");
248
249  // Short circuit properties that contain the name "delegate" or "dataSource",
250  // or have exact name "target" to have unsafe_unretained attribute.
251  if (PropertyName.equals("target") ||
252      (PropertyName.find("delegate") != StringRef::npos) ||
253      (PropertyName.find("dataSource") != StringRef::npos))
254    append_attr(PropertyString, "unsafe_unretained");
255  else if (Setter) {
256    const ParmVarDecl *argDecl = *Setter->param_begin();
257    QualType ArgType = Context.getCanonicalType(argDecl->getType());
258    Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime();
259    bool RetainableObject = ArgType->isObjCRetainableType();
260    if (RetainableObject && propertyLifetime == Qualifiers::OCL_Strong) {
261      if (const ObjCObjectPointerType *ObjPtrTy =
262          ArgType->getAs<ObjCObjectPointerType>()) {
263        ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
264        if (IDecl &&
265            IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying")))
266          append_attr(PropertyString, "copy");
267        else
268          append_attr(PropertyString, "retain");
269      }
270    } else if (propertyLifetime == Qualifiers::OCL_Weak)
271      // TODO. More precise determination of 'weak' attribute requires
272      // looking into setter's implementation for backing weak ivar.
273      append_attr(PropertyString, "weak");
274    else if (RetainableObject)
275      append_attr(PropertyString, "retain");
276  }
277  PropertyString += ')';
278
279  QualType RT = Getter->getResultType();
280  if (!isa<TypedefType>(RT)) {
281    // strip off any ARC lifetime qualifier.
282    QualType CanResultTy = Context.getCanonicalType(RT);
283    if (CanResultTy.getQualifiers().hasObjCLifetime()) {
284      Qualifiers Qs = CanResultTy.getQualifiers();
285      Qs.removeObjCLifetime();
286      RT = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs);
287    }
288  }
289  PropertyString += " ";
290  PropertyString += RT.getAsString(Context.getPrintingPolicy());
291  char LastChar = PropertyString[PropertyString.size()-1];
292  if (LastChar != '*')
293    PropertyString += " ";
294  if (LengthOfPrefix > 0) {
295    // property name must strip off "is" and lower case the first character
296    // after that; e.g. isContinuous will become continuous.
297    StringRef PropertyNameStringRef(PropertyNameString);
298    PropertyNameStringRef = PropertyNameStringRef.drop_front(LengthOfPrefix);
299    PropertyNameString = PropertyNameStringRef;
300    std::string NewPropertyNameString = PropertyNameString;
301    bool NoLowering = (isUppercase(NewPropertyNameString[0]) &&
302                       NewPropertyNameString.size() > 1 &&
303                       isUppercase(NewPropertyNameString[1]));
304    if (!NoLowering)
305      NewPropertyNameString[0] = toLowercase(NewPropertyNameString[0]);
306    PropertyString += NewPropertyNameString;
307  }
308  else
309    PropertyString += PropertyNameString;
310  SourceLocation StartGetterSelectorLoc = Getter->getSelectorStartLoc();
311  Selector GetterSelector = Getter->getSelector();
312
313  SourceLocation EndGetterSelectorLoc =
314    StartGetterSelectorLoc.getLocWithOffset(GetterSelector.getNameForSlot(0).size());
315  commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(),
316                                               EndGetterSelectorLoc),
317                 PropertyString);
318  if (Setter) {
319    SourceLocation EndLoc = Setter->getDeclaratorEndLoc();
320    // Get location past ';'
321    EndLoc = EndLoc.getLocWithOffset(1);
322    commit.remove(CharSourceRange::getCharRange(Setter->getLocStart(), EndLoc));
323  }
324  return true;
325}
326
327void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx,
328                                                      ObjCContainerDecl *D) {
329  if (D->isDeprecated())
330    return;
331
332  for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end();
333       M != MEnd; ++M) {
334    ObjCMethodDecl *Method = (*M);
335    if (Method->isDeprecated())
336      continue;
337    migrateProperty(Ctx, D, Method);
338    migrateNsReturnsInnerPointer(Ctx, Method);
339  }
340  for (ObjCContainerDecl::prop_iterator P = D->prop_begin(),
341       E = D->prop_end(); P != E; ++P) {
342    ObjCPropertyDecl *Prop = *P;
343    if (!P->isDeprecated())
344      migratePropertyNsReturnsInnerPointer(Ctx, Prop);
345  }
346}
347
348static bool
349ClassImplementsAllMethodsAndProperties(ASTContext &Ctx,
350                                      const ObjCImplementationDecl *ImpDecl,
351                                       const ObjCInterfaceDecl *IDecl,
352                                      ObjCProtocolDecl *Protocol) {
353  // In auto-synthesis, protocol properties are not synthesized. So,
354  // a conforming protocol must have its required properties declared
355  // in class interface.
356  bool HasAtleastOneRequiredProperty = false;
357  if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition())
358    for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
359         E = PDecl->prop_end(); P != E; ++P) {
360      ObjCPropertyDecl *Property = *P;
361      if (Property->getPropertyImplementation() == ObjCPropertyDecl::Optional)
362        continue;
363      HasAtleastOneRequiredProperty = true;
364      DeclContext::lookup_const_result R = IDecl->lookup(Property->getDeclName());
365      if (R.size() == 0) {
366        // Relax the rule and look into class's implementation for a synthesize
367        // or dynamic declaration. Class is implementing a property coming from
368        // another protocol. This still makes the target protocol as conforming.
369        if (!ImpDecl->FindPropertyImplDecl(
370                                  Property->getDeclName().getAsIdentifierInfo()))
371          return false;
372      }
373      else if (ObjCPropertyDecl *ClassProperty = dyn_cast<ObjCPropertyDecl>(R[0])) {
374          if ((ClassProperty->getPropertyAttributes()
375              != Property->getPropertyAttributes()) ||
376              !Ctx.hasSameType(ClassProperty->getType(), Property->getType()))
377            return false;
378      }
379      else
380        return false;
381    }
382
383  // At this point, all required properties in this protocol conform to those
384  // declared in the class.
385  // Check that class implements the required methods of the protocol too.
386  bool HasAtleastOneRequiredMethod = false;
387  if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) {
388    if (PDecl->meth_begin() == PDecl->meth_end())
389      return HasAtleastOneRequiredProperty;
390    for (ObjCContainerDecl::method_iterator M = PDecl->meth_begin(),
391         MEnd = PDecl->meth_end(); M != MEnd; ++M) {
392      ObjCMethodDecl *MD = (*M);
393      if (MD->isImplicit())
394        continue;
395      if (MD->getImplementationControl() == ObjCMethodDecl::Optional)
396        continue;
397      DeclContext::lookup_const_result R = ImpDecl->lookup(MD->getDeclName());
398      if (R.size() == 0)
399        return false;
400      bool match = false;
401      HasAtleastOneRequiredMethod = true;
402      for (unsigned I = 0, N = R.size(); I != N; ++I)
403        if (ObjCMethodDecl *ImpMD = dyn_cast<ObjCMethodDecl>(R[0]))
404          if (Ctx.ObjCMethodsAreEqual(MD, ImpMD)) {
405            match = true;
406            break;
407          }
408      if (!match)
409        return false;
410    }
411  }
412  if (HasAtleastOneRequiredProperty || HasAtleastOneRequiredMethod)
413    return true;
414  return false;
415}
416
417static bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl,
418                    llvm::SmallVectorImpl<ObjCProtocolDecl*> &ConformingProtocols,
419                    const NSAPI &NS, edit::Commit &commit) {
420  const ObjCList<ObjCProtocolDecl> &Protocols = IDecl->getReferencedProtocols();
421  std::string ClassString;
422  SourceLocation EndLoc =
423  IDecl->getSuperClass() ? IDecl->getSuperClassLoc() : IDecl->getLocation();
424
425  if (Protocols.empty()) {
426    ClassString = '<';
427    for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
428      ClassString += ConformingProtocols[i]->getNameAsString();
429      if (i != (e-1))
430        ClassString += ", ";
431    }
432    ClassString += "> ";
433  }
434  else {
435    ClassString = ", ";
436    for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
437      ClassString += ConformingProtocols[i]->getNameAsString();
438      if (i != (e-1))
439        ClassString += ", ";
440    }
441    ObjCInterfaceDecl::protocol_loc_iterator PL = IDecl->protocol_loc_end() - 1;
442    EndLoc = *PL;
443  }
444
445  commit.insertAfterToken(EndLoc, ClassString);
446  return true;
447}
448
449static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
450                                const TypedefDecl *TypedefDcl,
451                                const NSAPI &NS, edit::Commit &commit,
452                                bool IsNSIntegerType,
453                                bool NSOptions) {
454  std::string ClassString;
455  if (NSOptions)
456    ClassString = "typedef NS_OPTIONS(NSUInteger, ";
457  else
458    ClassString =
459      IsNSIntegerType ? "typedef NS_ENUM(NSInteger, "
460                      : "typedef NS_ENUM(NSUInteger, ";
461
462  ClassString += TypedefDcl->getIdentifier()->getName();
463  ClassString += ')';
464  SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart());
465  commit.replace(R, ClassString);
466  SourceLocation EndOfTypedefLoc = TypedefDcl->getLocEnd();
467  EndOfTypedefLoc = trans::findLocationAfterSemi(EndOfTypedefLoc, NS.getASTContext());
468  if (!EndOfTypedefLoc.isInvalid()) {
469    commit.remove(SourceRange(TypedefDcl->getLocStart(), EndOfTypedefLoc));
470    return true;
471  }
472  return false;
473}
474
475static bool rewriteToNSMacroDecl(const EnumDecl *EnumDcl,
476                                const TypedefDecl *TypedefDcl,
477                                const NSAPI &NS, edit::Commit &commit,
478                                 bool IsNSIntegerType) {
479  std::string ClassString =
480    IsNSIntegerType ? "NS_ENUM(NSInteger, " : "NS_OPTIONS(NSUInteger, ";
481  ClassString += TypedefDcl->getIdentifier()->getName();
482  ClassString += ')';
483  SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart());
484  commit.replace(R, ClassString);
485  SourceLocation TypedefLoc = TypedefDcl->getLocEnd();
486  commit.remove(SourceRange(TypedefLoc, TypedefLoc));
487  return true;
488}
489
490static bool UseNSOptionsMacro(Preprocessor &PP, ASTContext &Ctx,
491                              const EnumDecl *EnumDcl) {
492  bool PowerOfTwo = true;
493  bool AllHexdecimalEnumerator = true;
494  uint64_t MaxPowerOfTwoVal = 0;
495  for (EnumDecl::enumerator_iterator EI = EnumDcl->enumerator_begin(),
496       EE = EnumDcl->enumerator_end(); EI != EE; ++EI) {
497    EnumConstantDecl *Enumerator = (*EI);
498    const Expr *InitExpr = Enumerator->getInitExpr();
499    if (!InitExpr) {
500      PowerOfTwo = false;
501      AllHexdecimalEnumerator = false;
502      continue;
503    }
504    InitExpr = InitExpr->IgnoreParenCasts();
505    if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(InitExpr))
506      if (BO->isShiftOp() || BO->isBitwiseOp())
507        return true;
508
509    uint64_t EnumVal = Enumerator->getInitVal().getZExtValue();
510    if (PowerOfTwo && EnumVal) {
511      if (!llvm::isPowerOf2_64(EnumVal))
512        PowerOfTwo = false;
513      else if (EnumVal > MaxPowerOfTwoVal)
514        MaxPowerOfTwoVal = EnumVal;
515    }
516    if (AllHexdecimalEnumerator && EnumVal) {
517      bool FoundHexdecimalEnumerator = false;
518      SourceLocation EndLoc = Enumerator->getLocEnd();
519      Token Tok;
520      if (!PP.getRawToken(EndLoc, Tok, /*IgnoreWhiteSpace=*/true))
521        if (Tok.isLiteral() && Tok.getLength() > 2) {
522          if (const char *StringLit = Tok.getLiteralData())
523            FoundHexdecimalEnumerator =
524              (StringLit[0] == '0' && (toLowercase(StringLit[1]) == 'x'));
525        }
526      if (!FoundHexdecimalEnumerator)
527        AllHexdecimalEnumerator = false;
528    }
529  }
530  return AllHexdecimalEnumerator || (PowerOfTwo && (MaxPowerOfTwoVal > 2));
531}
532
533void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx,
534                                            const ObjCImplementationDecl *ImpDecl) {
535  const ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface();
536  if (!IDecl || ObjCProtocolDecls.empty() || IDecl->isDeprecated())
537    return;
538  // Find all implicit conforming protocols for this class
539  // and make them explicit.
540  llvm::SmallPtrSet<ObjCProtocolDecl *, 8> ExplicitProtocols;
541  Ctx.CollectInheritedProtocols(IDecl, ExplicitProtocols);
542  llvm::SmallVector<ObjCProtocolDecl *, 8> PotentialImplicitProtocols;
543
544  for (llvm::SmallPtrSet<ObjCProtocolDecl*, 32>::iterator I =
545       ObjCProtocolDecls.begin(),
546       E = ObjCProtocolDecls.end(); I != E; ++I)
547    if (!ExplicitProtocols.count(*I))
548      PotentialImplicitProtocols.push_back(*I);
549
550  if (PotentialImplicitProtocols.empty())
551    return;
552
553  // go through list of non-optional methods and properties in each protocol
554  // in the PotentialImplicitProtocols list. If class implements every one of the
555  // methods and properties, then this class conforms to this protocol.
556  llvm::SmallVector<ObjCProtocolDecl*, 8> ConformingProtocols;
557  for (unsigned i = 0, e = PotentialImplicitProtocols.size(); i != e; i++)
558    if (ClassImplementsAllMethodsAndProperties(Ctx, ImpDecl, IDecl,
559                                              PotentialImplicitProtocols[i]))
560      ConformingProtocols.push_back(PotentialImplicitProtocols[i]);
561
562  if (ConformingProtocols.empty())
563    return;
564
565  // Further reduce number of conforming protocols. If protocol P1 is in the list
566  // protocol P2 (P2<P1>), No need to include P1.
567  llvm::SmallVector<ObjCProtocolDecl*, 8> MinimalConformingProtocols;
568  for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
569    bool DropIt = false;
570    ObjCProtocolDecl *TargetPDecl = ConformingProtocols[i];
571    for (unsigned i1 = 0, e1 = ConformingProtocols.size(); i1 != e1; i1++) {
572      ObjCProtocolDecl *PDecl = ConformingProtocols[i1];
573      if (PDecl == TargetPDecl)
574        continue;
575      if (PDecl->lookupProtocolNamed(
576            TargetPDecl->getDeclName().getAsIdentifierInfo())) {
577        DropIt = true;
578        break;
579      }
580    }
581    if (!DropIt)
582      MinimalConformingProtocols.push_back(TargetPDecl);
583  }
584  edit::Commit commit(*Editor);
585  rewriteToObjCInterfaceDecl(IDecl, MinimalConformingProtocols,
586                             *NSAPIObj, commit);
587  Editor->commit(commit);
588}
589
590void ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
591                                           const EnumDecl *EnumDcl,
592                                           const TypedefDecl *TypedefDcl) {
593  if (!EnumDcl->isCompleteDefinition() || EnumDcl->getIdentifier() ||
594      !TypedefDcl->getIdentifier() ||
595      EnumDcl->isDeprecated() || TypedefDcl->isDeprecated())
596    return;
597
598  QualType qt = TypedefDcl->getTypeSourceInfo()->getType();
599  bool IsNSIntegerType = NSAPIObj->isObjCNSIntegerType(qt);
600  bool IsNSUIntegerType = !IsNSIntegerType && NSAPIObj->isObjCNSUIntegerType(qt);
601
602  if (!IsNSIntegerType && !IsNSUIntegerType) {
603    // Also check for typedef enum {...} TD;
604    if (const EnumType *EnumTy = qt->getAs<EnumType>()) {
605      if (EnumTy->getDecl() == EnumDcl) {
606        bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl);
607        if (NSOptions) {
608          if (!Ctx.Idents.get("NS_OPTIONS").hasMacroDefinition())
609            return;
610        }
611        else if (!Ctx.Idents.get("NS_ENUM").hasMacroDefinition())
612          return;
613        edit::Commit commit(*Editor);
614        rewriteToNSMacroDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit, !NSOptions);
615        Editor->commit(commit);
616      }
617    }
618    return;
619  }
620
621  // We may still use NS_OPTIONS based on what we find in the enumertor list.
622  bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl);
623  // NS_ENUM must be available.
624  if (IsNSIntegerType && !Ctx.Idents.get("NS_ENUM").hasMacroDefinition())
625    return;
626  // NS_OPTIONS must be available.
627  if (IsNSUIntegerType && !Ctx.Idents.get("NS_OPTIONS").hasMacroDefinition())
628    return;
629  edit::Commit commit(*Editor);
630  rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit, IsNSIntegerType, NSOptions);
631  Editor->commit(commit);
632}
633
634static void ReplaceWithInstancetype(const ObjCMigrateASTConsumer &ASTC,
635                                    ObjCMethodDecl *OM) {
636  SourceRange R;
637  std::string ClassString;
638  if (TypeSourceInfo *TSInfo =  OM->getResultTypeSourceInfo()) {
639    TypeLoc TL = TSInfo->getTypeLoc();
640    R = SourceRange(TL.getBeginLoc(), TL.getEndLoc());
641    ClassString = "instancetype";
642  }
643  else {
644    R = SourceRange(OM->getLocStart(), OM->getLocStart());
645    ClassString = OM->isInstanceMethod() ? '-' : '+';
646    ClassString += " (instancetype)";
647  }
648  edit::Commit commit(*ASTC.Editor);
649  commit.replace(R, ClassString);
650  ASTC.Editor->commit(commit);
651}
652
653void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx,
654                                                       ObjCContainerDecl *CDecl,
655                                                       ObjCMethodDecl *OM) {
656  ObjCInstanceTypeFamily OIT_Family =
657    Selector::getInstTypeMethodFamily(OM->getSelector());
658
659  std::string ClassName;
660  switch (OIT_Family) {
661    case OIT_None:
662      migrateFactoryMethod(Ctx, CDecl, OM);
663      return;
664    case OIT_Array:
665      ClassName = "NSArray";
666      break;
667    case OIT_Dictionary:
668      ClassName = "NSDictionary";
669      break;
670    case OIT_Singleton:
671      migrateFactoryMethod(Ctx, CDecl, OM, OIT_Singleton);
672      return;
673    case OIT_Init:
674      if (OM->getResultType()->isObjCIdType())
675        ReplaceWithInstancetype(*this, OM);
676      return;
677  }
678  if (!OM->getResultType()->isObjCIdType())
679    return;
680
681  ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
682  if (!IDecl) {
683    if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
684      IDecl = CatDecl->getClassInterface();
685    else if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(CDecl))
686      IDecl = ImpDecl->getClassInterface();
687  }
688  if (!IDecl ||
689      !IDecl->lookupInheritedClass(&Ctx.Idents.get(ClassName))) {
690    migrateFactoryMethod(Ctx, CDecl, OM);
691    return;
692  }
693  ReplaceWithInstancetype(*this, OM);
694}
695
696static bool TypeIsInnerPointer(QualType T) {
697  if (!T->isAnyPointerType())
698    return false;
699  if (T->isObjCObjectPointerType() || T->isObjCBuiltinType() ||
700      T->isBlockPointerType() || T->isFunctionPointerType() ||
701      ento::coreFoundation::isCFObjectRef(T))
702    return false;
703  // Also, typedef-of-pointer-to-incomplete-struct is something that we assume
704  // is not an innter pointer type.
705  QualType OrigT = T;
706  while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr()))
707    T = TD->getDecl()->getUnderlyingType();
708  if (OrigT == T || !T->isPointerType())
709    return true;
710  const PointerType* PT = T->getAs<PointerType>();
711  QualType UPointeeT = PT->getPointeeType().getUnqualifiedType();
712  if (UPointeeT->isRecordType()) {
713    const RecordType *RecordTy = UPointeeT->getAs<RecordType>();
714    if (!RecordTy->getDecl()->isCompleteDefinition())
715      return false;
716  }
717  return true;
718}
719
720static bool AttributesMatch(const Decl *Decl1, const Decl *Decl2) {
721  if (Decl1->hasAttrs() != Decl2->hasAttrs())
722    return false;
723
724  if (!Decl1->hasAttrs())
725    return true;
726
727  const AttrVec &Attrs1 = Decl1->getAttrs();
728  const AttrVec &Attrs2 = Decl2->getAttrs();
729  // This list is very small, so this need not be optimized.
730  for (unsigned i = 0, e = Attrs1.size(); i != e; i++) {
731    bool match = false;
732    for (unsigned j = 0, f = Attrs2.size(); j != f; j++) {
733      // Matching attribute kind only. We are not getting into
734      // details of the attributes. For all practical purposes
735      // this is sufficient.
736      if (Attrs1[i]->getKind() == Attrs2[j]->getKind()) {
737        match = true;
738        break;
739      }
740    }
741    if (!match)
742      return false;
743  }
744  return true;
745}
746
747static bool IsValidIdentifier(ASTContext &Ctx,
748                              const char *Name) {
749  if (!isIdentifierHead(Name[0]))
750    return false;
751  std::string NameString = Name;
752  NameString[0] = toLowercase(NameString[0]);
753  IdentifierInfo *II = &Ctx.Idents.get(NameString);
754  return II->getTokenID() ==  tok::identifier;
755}
756
757bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx,
758                             ObjCContainerDecl *D,
759                             ObjCMethodDecl *Method) {
760  if (Method->isPropertyAccessor() || !Method->isInstanceMethod() ||
761      Method->param_size() != 0)
762    return false;
763  // Is this method candidate to be a getter?
764  QualType GRT = Method->getResultType();
765  if (GRT->isVoidType())
766    return false;
767
768  Selector GetterSelector = Method->getSelector();
769  ObjCInstanceTypeFamily OIT_Family =
770    Selector::getInstTypeMethodFamily(GetterSelector);
771
772  if (OIT_Family != OIT_None)
773    return false;
774
775  IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0);
776  Selector SetterSelector =
777  SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
778                                         PP.getSelectorTable(),
779                                         getterName);
780  ObjCMethodDecl *SetterMethod = D->getInstanceMethod(SetterSelector);
781  unsigned LengthOfPrefix = 0;
782  if (!SetterMethod) {
783    // try a different naming convention for getter: isXxxxx
784    StringRef getterNameString = getterName->getName();
785    bool IsPrefix = getterNameString.startswith("is");
786    // Note that we don't want to change an isXXX method of retainable object
787    // type to property (readonly or otherwise).
788    if (IsPrefix && GRT->isObjCRetainableType())
789      return false;
790    if (IsPrefix || getterNameString.startswith("get")) {
791      LengthOfPrefix = (IsPrefix ? 2 : 3);
792      const char *CGetterName = getterNameString.data() + LengthOfPrefix;
793      // Make sure that first character after "is" or "get" prefix can
794      // start an identifier.
795      if (!IsValidIdentifier(Ctx, CGetterName))
796        return false;
797      if (CGetterName[0] && isUppercase(CGetterName[0])) {
798        getterName = &Ctx.Idents.get(CGetterName);
799        SetterSelector =
800        SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
801                                               PP.getSelectorTable(),
802                                               getterName);
803        SetterMethod = D->getInstanceMethod(SetterSelector);
804      }
805    }
806  }
807
808  if (SetterMethod) {
809    if (SetterMethod->isDeprecated() ||
810        !AttributesMatch(Method, SetterMethod))
811      return false;
812
813    // Is this a valid setter, matching the target getter?
814    QualType SRT = SetterMethod->getResultType();
815    if (!SRT->isVoidType())
816      return false;
817    const ParmVarDecl *argDecl = *SetterMethod->param_begin();
818    QualType ArgType = argDecl->getType();
819    if (!Ctx.hasSameUnqualifiedType(ArgType, GRT))
820      return false;
821    edit::Commit commit(*Editor);
822    rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit,
823                          LengthOfPrefix);
824    Editor->commit(commit);
825    return true;
826  }
827  else if (ASTMigrateActions & FrontendOptions::ObjCMT_ReadonlyProperty) {
828    // Try a non-void method with no argument (and no setter or property of same name
829    // as a 'readonly' property.
830    edit::Commit commit(*Editor);
831    rewriteToObjCProperty(Method, 0 /*SetterMethod*/, *NSAPIObj, commit,
832                          LengthOfPrefix);
833    Editor->commit(commit);
834    return true;
835  }
836  return false;
837}
838
839void ObjCMigrateASTConsumer::migrateNsReturnsInnerPointer(ASTContext &Ctx,
840                                                          ObjCMethodDecl *OM) {
841  if (OM->isImplicit() ||
842      !OM->isInstanceMethod() ||
843      OM->hasAttr<ObjCReturnsInnerPointerAttr>())
844    return;
845
846  QualType RT = OM->getResultType();
847  if (!TypeIsInnerPointer(RT) ||
848      !Ctx.Idents.get("NS_RETURNS_INNER_POINTER").hasMacroDefinition())
849    return;
850
851  edit::Commit commit(*Editor);
852  commit.insertBefore(OM->getLocEnd(), " NS_RETURNS_INNER_POINTER");
853  Editor->commit(commit);
854}
855
856void ObjCMigrateASTConsumer::migratePropertyNsReturnsInnerPointer(ASTContext &Ctx,
857                                                                  ObjCPropertyDecl *P) {
858  QualType T = P->getType();
859
860  if (!TypeIsInnerPointer(T) ||
861      !Ctx.Idents.get("NS_RETURNS_INNER_POINTER").hasMacroDefinition())
862    return;
863  edit::Commit commit(*Editor);
864  commit.insertBefore(P->getLocEnd(), " NS_RETURNS_INNER_POINTER ");
865  Editor->commit(commit);
866}
867
868void ObjCMigrateASTConsumer::migrateMethods(ASTContext &Ctx,
869                                                 ObjCContainerDecl *CDecl) {
870  if (CDecl->isDeprecated())
871    return;
872
873  // migrate methods which can have instancetype as their result type.
874  for (ObjCContainerDecl::method_iterator M = CDecl->meth_begin(),
875       MEnd = CDecl->meth_end();
876       M != MEnd; ++M) {
877    ObjCMethodDecl *Method = (*M);
878    if (Method->isDeprecated())
879      continue;
880    migrateMethodInstanceType(Ctx, CDecl, Method);
881  }
882}
883
884void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx,
885                                                  ObjCContainerDecl *CDecl,
886                                                  ObjCMethodDecl *OM,
887                                                  ObjCInstanceTypeFamily OIT_Family) {
888  if (OM->isInstanceMethod() ||
889      OM->getResultType() == Ctx.getObjCInstanceType() ||
890      !OM->getResultType()->isObjCIdType())
891    return;
892
893  // Candidate factory methods are + (id) NaMeXXX : ... which belong to a class
894  // NSYYYNamE with matching names be at least 3 characters long.
895  ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
896  if (!IDecl) {
897    if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
898      IDecl = CatDecl->getClassInterface();
899    else if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(CDecl))
900      IDecl = ImpDecl->getClassInterface();
901  }
902  if (!IDecl)
903    return;
904
905  std::string StringClassName = IDecl->getName();
906  StringRef LoweredClassName(StringClassName);
907  std::string StringLoweredClassName = LoweredClassName.lower();
908  LoweredClassName = StringLoweredClassName;
909
910  IdentifierInfo *MethodIdName = OM->getSelector().getIdentifierInfoForSlot(0);
911  // Handle method with no name at its first selector slot; e.g. + (id):(int)x.
912  if (!MethodIdName)
913    return;
914
915  std::string MethodName = MethodIdName->getName();
916  if (OIT_Family == OIT_Singleton) {
917    StringRef STRefMethodName(MethodName);
918    size_t len = 0;
919    if (STRefMethodName.startswith("standard"))
920      len = strlen("standard");
921    else if (STRefMethodName.startswith("shared"))
922      len = strlen("shared");
923    else if (STRefMethodName.startswith("default"))
924      len = strlen("default");
925    else
926      return;
927    MethodName = STRefMethodName.substr(len);
928  }
929  std::string MethodNameSubStr = MethodName.substr(0, 3);
930  StringRef MethodNamePrefix(MethodNameSubStr);
931  std::string StringLoweredMethodNamePrefix = MethodNamePrefix.lower();
932  MethodNamePrefix = StringLoweredMethodNamePrefix;
933  size_t Ix = LoweredClassName.rfind(MethodNamePrefix);
934  if (Ix == StringRef::npos)
935    return;
936  std::string ClassNamePostfix = LoweredClassName.substr(Ix);
937  StringRef LoweredMethodName(MethodName);
938  std::string StringLoweredMethodName = LoweredMethodName.lower();
939  LoweredMethodName = StringLoweredMethodName;
940  if (!LoweredMethodName.startswith(ClassNamePostfix))
941    return;
942  ReplaceWithInstancetype(*this, OM);
943}
944
945static bool IsVoidStarType(QualType Ty) {
946  if (!Ty->isPointerType())
947    return false;
948
949  while (const TypedefType *TD = dyn_cast<TypedefType>(Ty.getTypePtr()))
950    Ty = TD->getDecl()->getUnderlyingType();
951
952  // Is the type void*?
953  const PointerType* PT = Ty->getAs<PointerType>();
954  if (PT->getPointeeType().getUnqualifiedType()->isVoidType())
955    return true;
956  return IsVoidStarType(PT->getPointeeType());
957}
958
959/// AuditedType - This routine audits the type AT and returns false if it is one of known
960/// CF object types or of the "void *" variety. It returns true if we don't care about the type
961/// such as a non-pointer or pointers which have no ownership issues (such as "int *").
962static bool AuditedType (QualType AT) {
963  if (!AT->isAnyPointerType() && !AT->isBlockPointerType())
964    return true;
965  // FIXME. There isn't much we can say about CF pointer type; or is there?
966  if (ento::coreFoundation::isCFObjectRef(AT) ||
967      IsVoidStarType(AT) ||
968      // If an ObjC object is type, assuming that it is not a CF function and
969      // that it is an un-audited function.
970      AT->isObjCObjectPointerType() || AT->isObjCBuiltinType())
971    return false;
972  // All other pointers are assumed audited as harmless.
973  return true;
974}
975
976void ObjCMigrateASTConsumer::AnnotateImplicitBridging(ASTContext &Ctx) {
977  if (CFFunctionIBCandidates.empty())
978    return;
979  if (!Ctx.Idents.get("CF_IMPLICIT_BRIDGING_ENABLED").hasMacroDefinition()) {
980    CFFunctionIBCandidates.clear();
981    FileId = 0;
982    return;
983  }
984  // Insert CF_IMPLICIT_BRIDGING_ENABLE/CF_IMPLICIT_BRIDGING_DISABLED
985  const Decl *FirstFD = CFFunctionIBCandidates[0];
986  const Decl *LastFD  =
987    CFFunctionIBCandidates[CFFunctionIBCandidates.size()-1];
988  const char *PragmaString = "\nCF_IMPLICIT_BRIDGING_ENABLED\n\n";
989  edit::Commit commit(*Editor);
990  commit.insertBefore(FirstFD->getLocStart(), PragmaString);
991  PragmaString = "\n\nCF_IMPLICIT_BRIDGING_DISABLED\n";
992  SourceLocation EndLoc = LastFD->getLocEnd();
993  // get location just past end of function location.
994  EndLoc = PP.getLocForEndOfToken(EndLoc);
995  if (isa<FunctionDecl>(LastFD)) {
996    // For Methods, EndLoc points to the ending semcolon. So,
997    // not of these extra work is needed.
998    Token Tok;
999    // get locaiton of token that comes after end of function.
1000    bool Failed = PP.getRawToken(EndLoc, Tok, /*IgnoreWhiteSpace=*/true);
1001    if (!Failed)
1002      EndLoc = Tok.getLocation();
1003  }
1004  commit.insertAfterToken(EndLoc, PragmaString);
1005  Editor->commit(commit);
1006  FileId = 0;
1007  CFFunctionIBCandidates.clear();
1008}
1009
1010void ObjCMigrateASTConsumer::migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl) {
1011  if (Decl->isDeprecated())
1012    return;
1013
1014  if (Decl->hasAttr<CFAuditedTransferAttr>()) {
1015    assert(CFFunctionIBCandidates.empty() &&
1016           "Cannot have audited functions/methods inside user "
1017           "provided CF_IMPLICIT_BRIDGING_ENABLE");
1018    return;
1019  }
1020
1021  // Finction must be annotated first.
1022  if (const FunctionDecl *FuncDecl = dyn_cast<FunctionDecl>(Decl)) {
1023    CF_BRIDGING_KIND AuditKind = migrateAddFunctionAnnotation(Ctx, FuncDecl);
1024    if (AuditKind == CF_BRIDGING_ENABLE) {
1025      CFFunctionIBCandidates.push_back(Decl);
1026      if (!FileId)
1027        FileId = PP.getSourceManager().getFileID(Decl->getLocation()).getHashValue();
1028    }
1029    else if (AuditKind == CF_BRIDGING_MAY_INCLUDE) {
1030      if (!CFFunctionIBCandidates.empty()) {
1031        CFFunctionIBCandidates.push_back(Decl);
1032        if (!FileId)
1033          FileId = PP.getSourceManager().getFileID(Decl->getLocation()).getHashValue();
1034      }
1035    }
1036    else
1037      AnnotateImplicitBridging(Ctx);
1038  }
1039  else {
1040    migrateAddMethodAnnotation(Ctx, cast<ObjCMethodDecl>(Decl));
1041    AnnotateImplicitBridging(Ctx);
1042  }
1043}
1044
1045void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
1046                                              const CallEffects &CE,
1047                                              const FunctionDecl *FuncDecl,
1048                                              bool ResultAnnotated) {
1049  // Annotate function.
1050  if (!ResultAnnotated) {
1051    RetEffect Ret = CE.getReturnValue();
1052    const char *AnnotationString = 0;
1053    if (Ret.getObjKind() == RetEffect::CF) {
1054      if (Ret.isOwned() &&
1055          Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
1056        AnnotationString = " CF_RETURNS_RETAINED";
1057      else if (Ret.notOwned() &&
1058               Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition())
1059        AnnotationString = " CF_RETURNS_NOT_RETAINED";
1060    }
1061    else if (Ret.getObjKind() == RetEffect::ObjC) {
1062      if (Ret.isOwned() &&
1063          Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition())
1064        AnnotationString = " NS_RETURNS_RETAINED";
1065    }
1066
1067    if (AnnotationString) {
1068      edit::Commit commit(*Editor);
1069      commit.insertAfterToken(FuncDecl->getLocEnd(), AnnotationString);
1070      Editor->commit(commit);
1071    }
1072  }
1073  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1074  unsigned i = 0;
1075  for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
1076       pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
1077    const ParmVarDecl *pd = *pi;
1078    ArgEffect AE = AEArgs[i];
1079    if (AE == DecRef && !pd->getAttr<CFConsumedAttr>() &&
1080        Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
1081      edit::Commit commit(*Editor);
1082      commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
1083      Editor->commit(commit);
1084    }
1085    else if (AE == DecRefMsg && !pd->getAttr<NSConsumedAttr>() &&
1086             Ctx.Idents.get("NS_CONSUMED").hasMacroDefinition()) {
1087      edit::Commit commit(*Editor);
1088      commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
1089      Editor->commit(commit);
1090    }
1091  }
1092}
1093
1094
1095ObjCMigrateASTConsumer::CF_BRIDGING_KIND
1096  ObjCMigrateASTConsumer::migrateAddFunctionAnnotation(
1097                                                  ASTContext &Ctx,
1098                                                  const FunctionDecl *FuncDecl) {
1099  if (FuncDecl->hasBody())
1100    return CF_BRIDGING_NONE;
1101
1102  CallEffects CE  = CallEffects::getEffect(FuncDecl);
1103  bool FuncIsReturnAnnotated = (FuncDecl->getAttr<CFReturnsRetainedAttr>() ||
1104                                FuncDecl->getAttr<CFReturnsNotRetainedAttr>() ||
1105                                FuncDecl->getAttr<NSReturnsRetainedAttr>() ||
1106                                FuncDecl->getAttr<NSReturnsNotRetainedAttr>() ||
1107                                FuncDecl->getAttr<NSReturnsAutoreleasedAttr>());
1108
1109  // Trivial case of when funciton is annotated and has no argument.
1110  if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0)
1111    return CF_BRIDGING_NONE;
1112
1113  bool ReturnCFAudited = false;
1114  if (!FuncIsReturnAnnotated) {
1115    RetEffect Ret = CE.getReturnValue();
1116    if (Ret.getObjKind() == RetEffect::CF &&
1117        (Ret.isOwned() || Ret.notOwned()))
1118      ReturnCFAudited = true;
1119    else if (!AuditedType(FuncDecl->getResultType()))
1120      return CF_BRIDGING_NONE;
1121  }
1122
1123  // At this point result type is audited for potential inclusion.
1124  // Now, how about argument types.
1125  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1126  unsigned i = 0;
1127  bool ArgCFAudited = false;
1128  for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
1129       pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
1130    const ParmVarDecl *pd = *pi;
1131    ArgEffect AE = AEArgs[i];
1132    if (AE == DecRef /*CFConsumed annotated*/ || AE == IncRef) {
1133      if (AE == DecRef && !pd->getAttr<CFConsumedAttr>())
1134        ArgCFAudited = true;
1135      else if (AE == IncRef)
1136        ArgCFAudited = true;
1137    }
1138    else {
1139      QualType AT = pd->getType();
1140      if (!AuditedType(AT)) {
1141        AddCFAnnotations(Ctx, CE, FuncDecl, FuncIsReturnAnnotated);
1142        return CF_BRIDGING_NONE;
1143      }
1144    }
1145  }
1146  if (ReturnCFAudited || ArgCFAudited)
1147    return CF_BRIDGING_ENABLE;
1148
1149  return CF_BRIDGING_MAY_INCLUDE;
1150}
1151
1152void ObjCMigrateASTConsumer::migrateARCSafeAnnotation(ASTContext &Ctx,
1153                                                 ObjCContainerDecl *CDecl) {
1154  if (!isa<ObjCInterfaceDecl>(CDecl) || CDecl->isDeprecated())
1155    return;
1156
1157  // migrate methods which can have instancetype as their result type.
1158  for (ObjCContainerDecl::method_iterator M = CDecl->meth_begin(),
1159       MEnd = CDecl->meth_end();
1160       M != MEnd; ++M) {
1161    ObjCMethodDecl *Method = (*M);
1162    migrateCFAnnotation(Ctx, Method);
1163  }
1164}
1165
1166void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
1167                                              const CallEffects &CE,
1168                                              const ObjCMethodDecl *MethodDecl,
1169                                              bool ResultAnnotated) {
1170  // Annotate function.
1171  if (!ResultAnnotated) {
1172    RetEffect Ret = CE.getReturnValue();
1173    const char *AnnotationString = 0;
1174    if (Ret.getObjKind() == RetEffect::CF) {
1175      if (Ret.isOwned() &&
1176          Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
1177        AnnotationString = " CF_RETURNS_RETAINED";
1178      else if (Ret.notOwned() &&
1179               Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition())
1180        AnnotationString = " CF_RETURNS_NOT_RETAINED";
1181    }
1182    else if (Ret.getObjKind() == RetEffect::ObjC) {
1183      ObjCMethodFamily OMF = MethodDecl->getMethodFamily();
1184      switch (OMF) {
1185        case clang::OMF_alloc:
1186        case clang::OMF_new:
1187        case clang::OMF_copy:
1188        case clang::OMF_init:
1189        case clang::OMF_mutableCopy:
1190          break;
1191
1192        default:
1193          if (Ret.isOwned() &&
1194              Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition())
1195            AnnotationString = " NS_RETURNS_RETAINED";
1196          break;
1197      }
1198    }
1199
1200    if (AnnotationString) {
1201      edit::Commit commit(*Editor);
1202      commit.insertBefore(MethodDecl->getLocEnd(), AnnotationString);
1203      Editor->commit(commit);
1204    }
1205  }
1206  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1207  unsigned i = 0;
1208  for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
1209       pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
1210    const ParmVarDecl *pd = *pi;
1211    ArgEffect AE = AEArgs[i];
1212    if (AE == DecRef && !pd->getAttr<CFConsumedAttr>() &&
1213        Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
1214      edit::Commit commit(*Editor);
1215      commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
1216      Editor->commit(commit);
1217    }
1218  }
1219}
1220
1221void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
1222                                            ASTContext &Ctx,
1223                                            const ObjCMethodDecl *MethodDecl) {
1224  if (MethodDecl->hasBody() || MethodDecl->isImplicit())
1225    return;
1226
1227  CallEffects CE  = CallEffects::getEffect(MethodDecl);
1228  bool MethodIsReturnAnnotated = (MethodDecl->getAttr<CFReturnsRetainedAttr>() ||
1229                                  MethodDecl->getAttr<CFReturnsNotRetainedAttr>() ||
1230                                  MethodDecl->getAttr<NSReturnsRetainedAttr>() ||
1231                                  MethodDecl->getAttr<NSReturnsNotRetainedAttr>() ||
1232                                  MethodDecl->getAttr<NSReturnsAutoreleasedAttr>());
1233
1234  if (CE.getReceiver() ==  DecRefMsg &&
1235      !MethodDecl->getAttr<NSConsumesSelfAttr>() &&
1236      MethodDecl->getMethodFamily() != OMF_init &&
1237      MethodDecl->getMethodFamily() != OMF_release &&
1238      Ctx.Idents.get("NS_CONSUMES_SELF").hasMacroDefinition()) {
1239    edit::Commit commit(*Editor);
1240    commit.insertBefore(MethodDecl->getLocEnd(), " NS_CONSUMES_SELF");
1241    Editor->commit(commit);
1242  }
1243
1244  // Trivial case of when funciton is annotated and has no argument.
1245  if (MethodIsReturnAnnotated &&
1246      (MethodDecl->param_begin() == MethodDecl->param_end()))
1247    return;
1248
1249  if (!MethodIsReturnAnnotated) {
1250    RetEffect Ret = CE.getReturnValue();
1251    if ((Ret.getObjKind() == RetEffect::CF ||
1252         Ret.getObjKind() == RetEffect::ObjC) &&
1253        (Ret.isOwned() || Ret.notOwned())) {
1254      AddCFAnnotations(Ctx, CE, MethodDecl, false);
1255      return;
1256    }
1257    else if (!AuditedType(MethodDecl->getResultType()))
1258      return;
1259  }
1260
1261  // At this point result type is either annotated or audited.
1262  // Now, how about argument types.
1263  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1264  unsigned i = 0;
1265  for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
1266       pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
1267    const ParmVarDecl *pd = *pi;
1268    ArgEffect AE = AEArgs[i];
1269    if ((AE == DecRef && !pd->getAttr<CFConsumedAttr>()) || AE == IncRef ||
1270        !AuditedType(pd->getType())) {
1271      AddCFAnnotations(Ctx, CE, MethodDecl, MethodIsReturnAnnotated);
1272      return;
1273    }
1274  }
1275  return;
1276}
1277
1278namespace {
1279
1280class RewritesReceiver : public edit::EditsReceiver {
1281  Rewriter &Rewrite;
1282
1283public:
1284  RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
1285
1286  virtual void insert(SourceLocation loc, StringRef text) {
1287    Rewrite.InsertText(loc, text);
1288  }
1289  virtual void replace(CharSourceRange range, StringRef text) {
1290    Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
1291  }
1292};
1293
1294}
1295
1296static bool
1297IsReallyASystemHeader(ASTContext &Ctx, const FileEntry *file, FileID FID) {
1298  bool Invalid = false;
1299  const SrcMgr::SLocEntry &SEntry =
1300  Ctx.getSourceManager().getSLocEntry(FID, &Invalid);
1301  if (!Invalid && SEntry.isFile()) {
1302    const SrcMgr::FileInfo &FI = SEntry.getFile();
1303    if (!FI.hasLineDirectives()) {
1304      if (FI.getFileCharacteristic() == SrcMgr::C_ExternCSystem)
1305        return true;
1306      if (FI.getFileCharacteristic() == SrcMgr::C_System) {
1307        // This file is in a system header directory. Continue with commiting change
1308        // only if it is a user specified system directory because user put a
1309        // .system_framework file in the framework directory.
1310        StringRef Directory(file->getDir()->getName());
1311        size_t Ix = Directory.rfind(".framework");
1312        if (Ix == StringRef::npos)
1313          return true;
1314        std::string PatchToSystemFramework = Directory.slice(0, Ix+sizeof(".framework"));
1315        PatchToSystemFramework += ".system_framework";
1316        if (!llvm::sys::fs::exists(PatchToSystemFramework.data()))
1317          return true;
1318      }
1319    }
1320  }
1321  return false;
1322}
1323
1324void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
1325
1326  TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
1327  if (ASTMigrateActions & FrontendOptions::ObjCMT_Property) {
1328    for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end();
1329         D != DEnd; ++D) {
1330      if (unsigned FID =
1331            PP.getSourceManager().getFileID((*D)->getLocation()).getHashValue())
1332        if (FileId && FileId != FID)
1333          AnnotateImplicitBridging(Ctx);
1334
1335      if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D))
1336        migrateObjCInterfaceDecl(Ctx, CDecl);
1337      if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(*D))
1338        migrateObjCInterfaceDecl(Ctx, CatDecl);
1339      else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(*D))
1340        ObjCProtocolDecls.insert(PDecl);
1341      else if (const ObjCImplementationDecl *ImpDecl =
1342               dyn_cast<ObjCImplementationDecl>(*D))
1343        migrateProtocolConformance(Ctx, ImpDecl);
1344      else if (const EnumDecl *ED = dyn_cast<EnumDecl>(*D)) {
1345        DeclContext::decl_iterator N = D;
1346        ++N;
1347        if (N != DEnd)
1348          if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N))
1349            migrateNSEnumDecl(Ctx, ED, TD);
1350      }
1351      else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*D))
1352        migrateCFAnnotation(Ctx, FD);
1353
1354      if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(*D)) {
1355        // migrate methods which can have instancetype as their result type.
1356        migrateMethods(Ctx, CDecl);
1357        // annotate methods with CF annotations.
1358        migrateARCSafeAnnotation(Ctx, CDecl);
1359      }
1360    }
1361    AnnotateImplicitBridging(Ctx);
1362  }
1363
1364  Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
1365  RewritesReceiver Rec(rewriter);
1366  Editor->applyRewrites(Rec);
1367
1368  for (Rewriter::buffer_iterator
1369        I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) {
1370    FileID FID = I->first;
1371    RewriteBuffer &buf = I->second;
1372    const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID);
1373    assert(file);
1374    if (IsReallyASystemHeader(Ctx, file, FID))
1375      continue;
1376    SmallString<512> newText;
1377    llvm::raw_svector_ostream vecOS(newText);
1378    buf.write(vecOS);
1379    vecOS.flush();
1380    llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy(
1381                   StringRef(newText.data(), newText.size()), file->getName());
1382    SmallString<64> filePath(file->getName());
1383    FileMgr.FixupRelativePath(filePath);
1384    Remapper.remap(filePath.str(), memBuf);
1385  }
1386
1387  if (IsOutputFile) {
1388    Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics());
1389  } else {
1390    Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics());
1391  }
1392}
1393
1394bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) {
1395  CI.getDiagnostics().setIgnoreAllWarnings(true);
1396  return true;
1397}
1398
1399ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI,
1400                                                  StringRef InFile) {
1401  PPConditionalDirectiveRecord *
1402    PPRec = new PPConditionalDirectiveRecord(CI.getSourceManager());
1403  CI.getPreprocessor().addPPCallbacks(PPRec);
1404  return new ObjCMigrateASTConsumer(CI.getFrontendOpts().OutputFile,
1405                                    FrontendOptions::ObjCMT_All,
1406                                    Remapper,
1407                                    CI.getFileManager(),
1408                                    PPRec,
1409                                    CI.getPreprocessor(),
1410                                    /*isOutputFile=*/true);
1411}
1412