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