ObjCMT.cpp revision a346eb1188419d3f1698092edfbd66890b74163c
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->IgnoreParenCasts();
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  ObjCInstanceTypeFamily OIT_Family =
661    Selector::getInstTypeMethodFamily(OM->getSelector());
662
663  std::string ClassName;
664  switch (OIT_Family) {
665    case OIT_None:
666      migrateFactoryMethod(Ctx, CDecl, OM);
667      return;
668    case OIT_Array:
669      ClassName = "NSArray";
670      break;
671    case OIT_Dictionary:
672      ClassName = "NSDictionary";
673      break;
674    case OIT_Singleton:
675      migrateFactoryMethod(Ctx, CDecl, OM, OIT_Singleton);
676      return;
677    case OIT_Init:
678      if (OM->getResultType()->isObjCIdType())
679        ReplaceWithInstancetype(*this, OM);
680      return;
681  }
682  if (!OM->getResultType()->isObjCIdType())
683    return;
684
685  ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
686  if (!IDecl) {
687    if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
688      IDecl = CatDecl->getClassInterface();
689    else if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(CDecl))
690      IDecl = ImpDecl->getClassInterface();
691  }
692  if (!IDecl ||
693      !IDecl->lookupInheritedClass(&Ctx.Idents.get(ClassName))) {
694    migrateFactoryMethod(Ctx, CDecl, OM);
695    return;
696  }
697  ReplaceWithInstancetype(*this, OM);
698}
699
700static bool TypeIsInnerPointer(QualType T) {
701  if (!T->isAnyPointerType())
702    return false;
703  if (T->isObjCObjectPointerType() || T->isObjCBuiltinType() ||
704      T->isBlockPointerType() || ento::coreFoundation::isCFObjectRef(T))
705    return false;
706  // Also, typedef-of-pointer-to-incomplete-struct is something that we assume
707  // is not an innter pointer type.
708  QualType OrigT = T;
709  while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr()))
710    T = TD->getDecl()->getUnderlyingType();
711  if (OrigT == T || !T->isPointerType())
712    return true;
713  const PointerType* PT = T->getAs<PointerType>();
714  QualType UPointeeT = PT->getPointeeType().getUnqualifiedType();
715  if (UPointeeT->isRecordType()) {
716    const RecordType *RecordTy = UPointeeT->getAs<RecordType>();
717    if (!RecordTy->getDecl()->isCompleteDefinition())
718      return false;
719  }
720  return true;
721}
722
723static bool AttributesMatch(const Decl *Decl1, const Decl *Decl2) {
724  if (Decl1->hasAttrs() != Decl2->hasAttrs())
725    return false;
726
727  if (!Decl1->hasAttrs())
728    return true;
729
730  const AttrVec &Attrs1 = Decl1->getAttrs();
731  const AttrVec &Attrs2 = Decl2->getAttrs();
732  // This list is very small, so this need not be optimized.
733  for (unsigned i = 0, e = Attrs1.size(); i != e; i++) {
734    bool match = false;
735    for (unsigned j = 0, f = Attrs2.size(); j != f; j++) {
736      // Matching attribute kind only. We are not getting into
737      // details of the attributes. For all practical purposes
738      // this is sufficient.
739      if (Attrs1[i]->getKind() == Attrs2[j]->getKind()) {
740        match = true;
741        break;
742      }
743    }
744    if (!match)
745      return false;
746  }
747  return true;
748}
749
750bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx,
751                             ObjCContainerDecl *D,
752                             ObjCMethodDecl *Method) {
753  if (Method->isPropertyAccessor() || !Method->isInstanceMethod() ||
754      Method->param_size() != 0)
755    return false;
756  // Is this method candidate to be a getter?
757  QualType GRT = Method->getResultType();
758  if (GRT->isVoidType())
759    return false;
760
761  Selector GetterSelector = Method->getSelector();
762  IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0);
763  Selector SetterSelector =
764  SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
765                                         PP.getSelectorTable(),
766                                         getterName);
767  ObjCMethodDecl *SetterMethod = D->getInstanceMethod(SetterSelector);
768  unsigned LengthOfPrefix = 0;
769  if (!SetterMethod) {
770    // try a different naming convention for getter: isXxxxx
771    StringRef getterNameString = getterName->getName();
772    bool IsPrefix = getterNameString.startswith("is");
773    // Note that we don't want to change an isXXX method of retainable object
774    // type to property (readonly or otherwise).
775    if (IsPrefix && GRT->isObjCRetainableType())
776      return false;
777    if (IsPrefix || getterNameString.startswith("get")) {
778      LengthOfPrefix = (IsPrefix ? 2 : 3);
779      const char *CGetterName = getterNameString.data() + LengthOfPrefix;
780      // Make sure that first character after "is" or "get" prefix can
781      // start an identifier.
782      if (!isIdentifierHead(CGetterName[0]))
783        return false;
784      if (CGetterName[0] && isUppercase(CGetterName[0])) {
785        getterName = &Ctx.Idents.get(CGetterName);
786        SetterSelector =
787        SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
788                                               PP.getSelectorTable(),
789                                               getterName);
790        SetterMethod = D->getInstanceMethod(SetterSelector);
791      }
792    }
793  }
794
795  if (SetterMethod) {
796    if (SetterMethod->isDeprecated() ||
797        !AttributesMatch(Method, SetterMethod))
798      return false;
799
800    // Is this a valid setter, matching the target getter?
801    QualType SRT = SetterMethod->getResultType();
802    if (!SRT->isVoidType())
803      return false;
804    const ParmVarDecl *argDecl = *SetterMethod->param_begin();
805    QualType ArgType = argDecl->getType();
806    if (!Ctx.hasSameUnqualifiedType(ArgType, GRT))
807      return false;
808    edit::Commit commit(*Editor);
809    rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit,
810                          LengthOfPrefix);
811    Editor->commit(commit);
812    return true;
813  }
814  else if (MigrateReadonlyProperty) {
815    // Try a non-void method with no argument (and no setter or property of same name
816    // as a 'readonly' property.
817    edit::Commit commit(*Editor);
818    rewriteToObjCProperty(Method, 0 /*SetterMethod*/, *NSAPIObj, commit,
819                          LengthOfPrefix);
820    Editor->commit(commit);
821    return true;
822  }
823  return false;
824}
825
826void ObjCMigrateASTConsumer::migrateNsReturnsInnerPointer(ASTContext &Ctx,
827                                                          ObjCMethodDecl *OM) {
828  if (OM->hasAttr<ObjCReturnsInnerPointerAttr>())
829    return;
830
831  QualType RT = OM->getResultType();
832  if (!TypeIsInnerPointer(RT) ||
833      !Ctx.Idents.get("NS_RETURNS_INNER_POINTER").hasMacroDefinition())
834    return;
835
836  edit::Commit commit(*Editor);
837  commit.insertBefore(OM->getLocEnd(), " NS_RETURNS_INNER_POINTER");
838  Editor->commit(commit);
839}
840
841void ObjCMigrateASTConsumer::migrateMethods(ASTContext &Ctx,
842                                                 ObjCContainerDecl *CDecl) {
843  if (CDecl->isDeprecated())
844    return;
845
846  // migrate methods which can have instancetype as their result type.
847  for (ObjCContainerDecl::method_iterator M = CDecl->meth_begin(),
848       MEnd = CDecl->meth_end();
849       M != MEnd; ++M) {
850    ObjCMethodDecl *Method = (*M);
851    if (Method->isDeprecated())
852      continue;
853    migrateMethodInstanceType(Ctx, CDecl, Method);
854  }
855}
856
857void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx,
858                                                  ObjCContainerDecl *CDecl,
859                                                  ObjCMethodDecl *OM,
860                                                  ObjCInstanceTypeFamily OIT_Family) {
861  if (OM->isInstanceMethod() ||
862      OM->getResultType() == Ctx.getObjCInstanceType() ||
863      !OM->getResultType()->isObjCIdType())
864    return;
865
866  // Candidate factory methods are + (id) NaMeXXX : ... which belong to a class
867  // NSYYYNamE with matching names be at least 3 characters long.
868  ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
869  if (!IDecl) {
870    if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
871      IDecl = CatDecl->getClassInterface();
872    else if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(CDecl))
873      IDecl = ImpDecl->getClassInterface();
874  }
875  if (!IDecl)
876    return;
877
878  std::string StringClassName = IDecl->getName();
879  StringRef LoweredClassName(StringClassName);
880  std::string StringLoweredClassName = LoweredClassName.lower();
881  LoweredClassName = StringLoweredClassName;
882
883  IdentifierInfo *MethodIdName = OM->getSelector().getIdentifierInfoForSlot(0);
884  // Handle method with no name at its first selector slot; e.g. + (id):(int)x.
885  if (!MethodIdName)
886    return;
887
888  std::string MethodName = MethodIdName->getName();
889  if (OIT_Family == OIT_Singleton) {
890    StringRef STRefMethodName(MethodName);
891    size_t len = 0;
892    if (STRefMethodName.startswith("standard"))
893      len = strlen("standard");
894    else if (STRefMethodName.startswith("shared"))
895      len = strlen("shared");
896    else if (STRefMethodName.startswith("default"))
897      len = strlen("default");
898    else
899      return;
900    MethodName = STRefMethodName.substr(len);
901  }
902  std::string MethodNameSubStr = MethodName.substr(0, 3);
903  StringRef MethodNamePrefix(MethodNameSubStr);
904  std::string StringLoweredMethodNamePrefix = MethodNamePrefix.lower();
905  MethodNamePrefix = StringLoweredMethodNamePrefix;
906  size_t Ix = LoweredClassName.rfind(MethodNamePrefix);
907  if (Ix == StringRef::npos)
908    return;
909  std::string ClassNamePostfix = LoweredClassName.substr(Ix);
910  StringRef LoweredMethodName(MethodName);
911  std::string StringLoweredMethodName = LoweredMethodName.lower();
912  LoweredMethodName = StringLoweredMethodName;
913  if (!LoweredMethodName.startswith(ClassNamePostfix))
914    return;
915  ReplaceWithInstancetype(*this, OM);
916}
917
918static bool IsVoidStarType(QualType Ty) {
919  if (!Ty->isPointerType())
920    return false;
921
922  while (const TypedefType *TD = dyn_cast<TypedefType>(Ty.getTypePtr()))
923    Ty = TD->getDecl()->getUnderlyingType();
924
925  // Is the type void*?
926  const PointerType* PT = Ty->getAs<PointerType>();
927  if (PT->getPointeeType().getUnqualifiedType()->isVoidType())
928    return true;
929  return IsVoidStarType(PT->getPointeeType());
930}
931
932/// AuditedType - This routine audits the type AT and returns false if it is one of known
933/// CF object types or of the "void *" variety. It returns true if we don't care about the type
934/// such as a non-pointer or pointers which have no ownership issues (such as "int *").
935static bool AuditedType (QualType AT) {
936  if (!AT->isAnyPointerType() && !AT->isBlockPointerType())
937    return true;
938  // FIXME. There isn't much we can say about CF pointer type; or is there?
939  if (ento::coreFoundation::isCFObjectRef(AT) ||
940      IsVoidStarType(AT) ||
941      // If an ObjC object is type, assuming that it is not a CF function and
942      // that it is an un-audited function.
943      AT->isObjCObjectPointerType() || AT->isObjCBuiltinType())
944    return false;
945  // All other pointers are assumed audited as harmless.
946  return true;
947}
948
949void ObjCMigrateASTConsumer::AnnotateImplicitBridging(ASTContext &Ctx) {
950  if (CFFunctionIBCandidates.empty())
951    return;
952  if (!Ctx.Idents.get("CF_IMPLICIT_BRIDGING_ENABLED").hasMacroDefinition()) {
953    CFFunctionIBCandidates.clear();
954    FileId = 0;
955    return;
956  }
957  // Insert CF_IMPLICIT_BRIDGING_ENABLE/CF_IMPLICIT_BRIDGING_DISABLED
958  const Decl *FirstFD = CFFunctionIBCandidates[0];
959  const Decl *LastFD  =
960    CFFunctionIBCandidates[CFFunctionIBCandidates.size()-1];
961  const char *PragmaString = "\nCF_IMPLICIT_BRIDGING_ENABLED\n\n";
962  edit::Commit commit(*Editor);
963  commit.insertBefore(FirstFD->getLocStart(), PragmaString);
964  PragmaString = "\n\nCF_IMPLICIT_BRIDGING_DISABLED\n";
965  SourceLocation EndLoc = LastFD->getLocEnd();
966  // get location just past end of function location.
967  EndLoc = PP.getLocForEndOfToken(EndLoc);
968  if (isa<FunctionDecl>(LastFD)) {
969    // For Methods, EndLoc points to the ending semcolon. So,
970    // not of these extra work is needed.
971    Token Tok;
972    // get locaiton of token that comes after end of function.
973    bool Failed = PP.getRawToken(EndLoc, Tok, /*IgnoreWhiteSpace=*/true);
974    if (!Failed)
975      EndLoc = Tok.getLocation();
976  }
977  commit.insertAfterToken(EndLoc, PragmaString);
978  Editor->commit(commit);
979  FileId = 0;
980  CFFunctionIBCandidates.clear();
981}
982
983void ObjCMigrateASTConsumer::migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl) {
984  if (Decl->isDeprecated())
985    return;
986
987  if (Decl->hasAttr<CFAuditedTransferAttr>()) {
988    assert(CFFunctionIBCandidates.empty() &&
989           "Cannot have audited functions/methods inside user "
990           "provided CF_IMPLICIT_BRIDGING_ENABLE");
991    return;
992  }
993
994  // Finction must be annotated first.
995  if (const FunctionDecl *FuncDecl = dyn_cast<FunctionDecl>(Decl)) {
996    CF_BRIDGING_KIND AuditKind = migrateAddFunctionAnnotation(Ctx, FuncDecl);
997    if (AuditKind == CF_BRIDGING_ENABLE) {
998      CFFunctionIBCandidates.push_back(Decl);
999      if (!FileId)
1000        FileId = PP.getSourceManager().getFileID(Decl->getLocation()).getHashValue();
1001    }
1002    else if (AuditKind == CF_BRIDGING_MAY_INCLUDE) {
1003      if (!CFFunctionIBCandidates.empty()) {
1004        CFFunctionIBCandidates.push_back(Decl);
1005        if (!FileId)
1006          FileId = PP.getSourceManager().getFileID(Decl->getLocation()).getHashValue();
1007      }
1008    }
1009    else
1010      AnnotateImplicitBridging(Ctx);
1011  }
1012  else {
1013    migrateAddMethodAnnotation(Ctx, cast<ObjCMethodDecl>(Decl));
1014    AnnotateImplicitBridging(Ctx);
1015  }
1016}
1017
1018void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
1019                                              const CallEffects &CE,
1020                                              const FunctionDecl *FuncDecl,
1021                                              bool ResultAnnotated) {
1022  // Annotate function.
1023  if (!ResultAnnotated) {
1024    RetEffect Ret = CE.getReturnValue();
1025    const char *AnnotationString = 0;
1026    if (Ret.getObjKind() == RetEffect::CF) {
1027      if (Ret.isOwned() &&
1028          Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
1029        AnnotationString = " CF_RETURNS_RETAINED";
1030      else if (Ret.notOwned() &&
1031               Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition())
1032        AnnotationString = " CF_RETURNS_NOT_RETAINED";
1033    }
1034    else if (Ret.getObjKind() == RetEffect::ObjC) {
1035      if (Ret.isOwned() &&
1036          Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition())
1037        AnnotationString = " NS_RETURNS_RETAINED";
1038    }
1039
1040    if (AnnotationString) {
1041      edit::Commit commit(*Editor);
1042      commit.insertAfterToken(FuncDecl->getLocEnd(), AnnotationString);
1043      Editor->commit(commit);
1044    }
1045  }
1046  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1047  unsigned i = 0;
1048  for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
1049       pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
1050    const ParmVarDecl *pd = *pi;
1051    ArgEffect AE = AEArgs[i];
1052    if (AE == DecRef && !pd->getAttr<CFConsumedAttr>() &&
1053        Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
1054      edit::Commit commit(*Editor);
1055      commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
1056      Editor->commit(commit);
1057    }
1058    else if (AE == DecRefMsg && !pd->getAttr<NSConsumedAttr>() &&
1059             Ctx.Idents.get("NS_CONSUMED").hasMacroDefinition()) {
1060      edit::Commit commit(*Editor);
1061      commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
1062      Editor->commit(commit);
1063    }
1064  }
1065}
1066
1067
1068ObjCMigrateASTConsumer::CF_BRIDGING_KIND
1069  ObjCMigrateASTConsumer::migrateAddFunctionAnnotation(
1070                                                  ASTContext &Ctx,
1071                                                  const FunctionDecl *FuncDecl) {
1072  if (FuncDecl->hasBody())
1073    return CF_BRIDGING_NONE;
1074
1075  CallEffects CE  = CallEffects::getEffect(FuncDecl);
1076  bool FuncIsReturnAnnotated = (FuncDecl->getAttr<CFReturnsRetainedAttr>() ||
1077                                FuncDecl->getAttr<CFReturnsNotRetainedAttr>() ||
1078                                FuncDecl->getAttr<NSReturnsRetainedAttr>() ||
1079                                FuncDecl->getAttr<NSReturnsNotRetainedAttr>() ||
1080                                FuncDecl->getAttr<NSReturnsAutoreleasedAttr>());
1081
1082  // Trivial case of when funciton is annotated and has no argument.
1083  if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0)
1084    return CF_BRIDGING_NONE;
1085
1086  bool ReturnCFAudited = false;
1087  if (!FuncIsReturnAnnotated) {
1088    RetEffect Ret = CE.getReturnValue();
1089    if (Ret.getObjKind() == RetEffect::CF &&
1090        (Ret.isOwned() || Ret.notOwned()))
1091      ReturnCFAudited = true;
1092    else if (!AuditedType(FuncDecl->getResultType()))
1093      return CF_BRIDGING_NONE;
1094  }
1095
1096  // At this point result type is audited for potential inclusion.
1097  // Now, how about argument types.
1098  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1099  unsigned i = 0;
1100  bool ArgCFAudited = false;
1101  for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
1102       pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
1103    const ParmVarDecl *pd = *pi;
1104    ArgEffect AE = AEArgs[i];
1105    if (AE == DecRef /*CFConsumed annotated*/ || AE == IncRef) {
1106      if (AE == DecRef && !pd->getAttr<CFConsumedAttr>())
1107        ArgCFAudited = true;
1108      else if (AE == IncRef)
1109        ArgCFAudited = true;
1110    }
1111    else {
1112      QualType AT = pd->getType();
1113      if (!AuditedType(AT)) {
1114        AddCFAnnotations(Ctx, CE, FuncDecl, FuncIsReturnAnnotated);
1115        return CF_BRIDGING_NONE;
1116      }
1117    }
1118  }
1119  if (ReturnCFAudited || ArgCFAudited)
1120    return CF_BRIDGING_ENABLE;
1121
1122  return CF_BRIDGING_MAY_INCLUDE;
1123}
1124
1125void ObjCMigrateASTConsumer::migrateARCSafeAnnotation(ASTContext &Ctx,
1126                                                 ObjCContainerDecl *CDecl) {
1127  if (!isa<ObjCInterfaceDecl>(CDecl) || CDecl->isDeprecated())
1128    return;
1129
1130  // migrate methods which can have instancetype as their result type.
1131  for (ObjCContainerDecl::method_iterator M = CDecl->meth_begin(),
1132       MEnd = CDecl->meth_end();
1133       M != MEnd; ++M) {
1134    ObjCMethodDecl *Method = (*M);
1135    migrateCFAnnotation(Ctx, Method);
1136  }
1137}
1138
1139void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
1140                                              const CallEffects &CE,
1141                                              const ObjCMethodDecl *MethodDecl,
1142                                              bool ResultAnnotated) {
1143  // Annotate function.
1144  if (!ResultAnnotated) {
1145    RetEffect Ret = CE.getReturnValue();
1146    const char *AnnotationString = 0;
1147    if (Ret.getObjKind() == RetEffect::CF) {
1148      if (Ret.isOwned() &&
1149          Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
1150        AnnotationString = " CF_RETURNS_RETAINED";
1151      else if (Ret.notOwned() &&
1152               Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition())
1153        AnnotationString = " CF_RETURNS_NOT_RETAINED";
1154    }
1155    else if (Ret.getObjKind() == RetEffect::ObjC) {
1156      ObjCMethodFamily OMF = MethodDecl->getMethodFamily();
1157      switch (OMF) {
1158        case clang::OMF_alloc:
1159        case clang::OMF_new:
1160        case clang::OMF_copy:
1161        case clang::OMF_init:
1162        case clang::OMF_mutableCopy:
1163          break;
1164
1165        default:
1166          if (Ret.isOwned() &&
1167              Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition())
1168            AnnotationString = " NS_RETURNS_RETAINED";
1169          break;
1170      }
1171    }
1172
1173    if (AnnotationString) {
1174      edit::Commit commit(*Editor);
1175      commit.insertBefore(MethodDecl->getLocEnd(), AnnotationString);
1176      Editor->commit(commit);
1177    }
1178  }
1179  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1180  unsigned i = 0;
1181  for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
1182       pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
1183    const ParmVarDecl *pd = *pi;
1184    ArgEffect AE = AEArgs[i];
1185    if (AE == DecRef && !pd->getAttr<CFConsumedAttr>() &&
1186        Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
1187      edit::Commit commit(*Editor);
1188      commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
1189      Editor->commit(commit);
1190    }
1191  }
1192}
1193
1194void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
1195                                            ASTContext &Ctx,
1196                                            const ObjCMethodDecl *MethodDecl) {
1197  if (MethodDecl->hasBody() || MethodDecl->isImplicit())
1198    return;
1199
1200  CallEffects CE  = CallEffects::getEffect(MethodDecl);
1201  bool MethodIsReturnAnnotated = (MethodDecl->getAttr<CFReturnsRetainedAttr>() ||
1202                                  MethodDecl->getAttr<CFReturnsNotRetainedAttr>() ||
1203                                  MethodDecl->getAttr<NSReturnsRetainedAttr>() ||
1204                                  MethodDecl->getAttr<NSReturnsNotRetainedAttr>() ||
1205                                  MethodDecl->getAttr<NSReturnsAutoreleasedAttr>());
1206
1207  if (CE.getReceiver() ==  DecRefMsg &&
1208      !MethodDecl->getAttr<NSConsumesSelfAttr>() &&
1209      MethodDecl->getMethodFamily() != OMF_init &&
1210      MethodDecl->getMethodFamily() != OMF_release &&
1211      Ctx.Idents.get("NS_CONSUMES_SELF").hasMacroDefinition()) {
1212    edit::Commit commit(*Editor);
1213    commit.insertBefore(MethodDecl->getLocEnd(), " NS_CONSUMES_SELF");
1214    Editor->commit(commit);
1215  }
1216
1217  // Trivial case of when funciton is annotated and has no argument.
1218  if (MethodIsReturnAnnotated &&
1219      (MethodDecl->param_begin() == MethodDecl->param_end()))
1220    return;
1221
1222  if (!MethodIsReturnAnnotated) {
1223    RetEffect Ret = CE.getReturnValue();
1224    if ((Ret.getObjKind() == RetEffect::CF ||
1225         Ret.getObjKind() == RetEffect::ObjC) &&
1226        (Ret.isOwned() || Ret.notOwned())) {
1227      AddCFAnnotations(Ctx, CE, MethodDecl, false);
1228      return;
1229    }
1230    else if (!AuditedType(MethodDecl->getResultType()))
1231      return;
1232  }
1233
1234  // At this point result type is either annotated or audited.
1235  // Now, how about argument types.
1236  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1237  unsigned i = 0;
1238  for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
1239       pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
1240    const ParmVarDecl *pd = *pi;
1241    ArgEffect AE = AEArgs[i];
1242    if ((AE == DecRef && !pd->getAttr<CFConsumedAttr>()) || AE == IncRef ||
1243        !AuditedType(pd->getType())) {
1244      AddCFAnnotations(Ctx, CE, MethodDecl, MethodIsReturnAnnotated);
1245      return;
1246    }
1247  }
1248  return;
1249}
1250
1251namespace {
1252
1253class RewritesReceiver : public edit::EditsReceiver {
1254  Rewriter &Rewrite;
1255
1256public:
1257  RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
1258
1259  virtual void insert(SourceLocation loc, StringRef text) {
1260    Rewrite.InsertText(loc, text);
1261  }
1262  virtual void replace(CharSourceRange range, StringRef text) {
1263    Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
1264  }
1265};
1266
1267}
1268
1269void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
1270
1271  TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
1272  if (MigrateProperty) {
1273    for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end();
1274         D != DEnd; ++D) {
1275      if (unsigned FID =
1276            PP.getSourceManager().getFileID((*D)->getLocation()).getHashValue())
1277        if (FileId && FileId != FID)
1278          AnnotateImplicitBridging(Ctx);
1279
1280      if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D))
1281        migrateObjCInterfaceDecl(Ctx, CDecl);
1282      if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(*D))
1283        migrateObjCInterfaceDecl(Ctx, CatDecl);
1284      else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(*D))
1285        ObjCProtocolDecls.insert(PDecl);
1286      else if (const ObjCImplementationDecl *ImpDecl =
1287               dyn_cast<ObjCImplementationDecl>(*D))
1288        migrateProtocolConformance(Ctx, ImpDecl);
1289      else if (const EnumDecl *ED = dyn_cast<EnumDecl>(*D)) {
1290        DeclContext::decl_iterator N = D;
1291        ++N;
1292        if (N != DEnd)
1293          if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N))
1294            migrateNSEnumDecl(Ctx, ED, TD);
1295      }
1296      else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*D))
1297        migrateCFAnnotation(Ctx, FD);
1298
1299      if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(*D)) {
1300        // migrate methods which can have instancetype as their result type.
1301        migrateMethods(Ctx, CDecl);
1302        // annotate methods with CF annotations.
1303        migrateARCSafeAnnotation(Ctx, CDecl);
1304      }
1305    }
1306    AnnotateImplicitBridging(Ctx);
1307  }
1308
1309  Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
1310  RewritesReceiver Rec(rewriter);
1311  Editor->applyRewrites(Rec);
1312
1313  for (Rewriter::buffer_iterator
1314        I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) {
1315    FileID FID = I->first;
1316    RewriteBuffer &buf = I->second;
1317    const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID);
1318    assert(file);
1319    SmallString<512> newText;
1320    llvm::raw_svector_ostream vecOS(newText);
1321    buf.write(vecOS);
1322    vecOS.flush();
1323    llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy(
1324                   StringRef(newText.data(), newText.size()), file->getName());
1325    SmallString<64> filePath(file->getName());
1326    FileMgr.FixupRelativePath(filePath);
1327    Remapper.remap(filePath.str(), memBuf);
1328  }
1329
1330  if (IsOutputFile) {
1331    Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics());
1332  } else {
1333    Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics());
1334  }
1335}
1336
1337bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) {
1338  CI.getDiagnostics().setIgnoreAllWarnings(true);
1339  return true;
1340}
1341
1342ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI,
1343                                                  StringRef InFile) {
1344  PPConditionalDirectiveRecord *
1345    PPRec = new PPConditionalDirectiveRecord(CI.getSourceManager());
1346  CI.getPreprocessor().addPPCallbacks(PPRec);
1347  return new ObjCMigrateASTConsumer(CI.getFrontendOpts().OutputFile,
1348                                    /*MigrateLiterals=*/true,
1349                                    /*MigrateSubscripting=*/true,
1350                                    /*MigrateProperty*/true,
1351                                    /*MigrateReadonlyProperty*/true,
1352                                    Remapper,
1353                                    CI.getFileManager(),
1354                                    PPRec,
1355                                    CI.getPreprocessor(),
1356                                    /*isOutputFile=*/true);
1357}
1358