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