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