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