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/ARCMT.h"
12 #include "clang/ARCMigrate/ARCMTActions.h"
13 #include "clang/AST/ASTConsumer.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/Attr.h"
16 #include "clang/AST/NSAPI.h"
17 #include "clang/AST/ParentMap.h"
18 #include "clang/AST/RecursiveASTVisitor.h"
19 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
20 #include "clang/Basic/FileManager.h"
21 #include "clang/Edit/Commit.h"
22 #include "clang/Edit/EditedSource.h"
23 #include "clang/Edit/EditsReceiver.h"
24 #include "clang/Edit/Rewriters.h"
25 #include "clang/Frontend/CompilerInstance.h"
26 #include "clang/Frontend/MultiplexConsumer.h"
27 #include "clang/Lex/PPConditionalDirectiveRecord.h"
28 #include "clang/Lex/Preprocessor.h"
29 #include "clang/Rewrite/Core/Rewriter.h"
30 #include "clang/StaticAnalyzer/Checkers/ObjCRetainCount.h"
31 #include "llvm/ADT/SmallString.h"
32 #include "llvm/Support/Path.h"
33 #include "llvm/Support/SourceMgr.h"
34 #include "llvm/Support/YAMLParser.h"
35 
36 using namespace clang;
37 using namespace arcmt;
38 using namespace ento::objc_retain;
39 
40 namespace {
41 
42 class ObjCMigrateASTConsumer : public ASTConsumer {
43   enum CF_BRIDGING_KIND {
44     CF_BRIDGING_NONE,
45     CF_BRIDGING_ENABLE,
46     CF_BRIDGING_MAY_INCLUDE
47   };
48 
49   void migrateDecl(Decl *D);
50   void migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCContainerDecl *D);
51   void migrateProtocolConformance(ASTContext &Ctx,
52                                   const ObjCImplementationDecl *ImpDecl);
53   void CacheObjCNSIntegerTypedefed(const TypedefDecl *TypedefDcl);
54   bool migrateNSEnumDecl(ASTContext &Ctx, const EnumDecl *EnumDcl,
55                      const TypedefDecl *TypedefDcl);
56   void migrateAllMethodInstaceType(ASTContext &Ctx, ObjCContainerDecl *CDecl);
57   void migrateMethodInstanceType(ASTContext &Ctx, ObjCContainerDecl *CDecl,
58                                  ObjCMethodDecl *OM);
59   bool migrateProperty(ASTContext &Ctx, ObjCContainerDecl *D, ObjCMethodDecl *OM);
60   void migrateNsReturnsInnerPointer(ASTContext &Ctx, ObjCMethodDecl *OM);
61   void migratePropertyNsReturnsInnerPointer(ASTContext &Ctx, ObjCPropertyDecl *P);
62   void migrateFactoryMethod(ASTContext &Ctx, ObjCContainerDecl *CDecl,
63                             ObjCMethodDecl *OM,
64                             ObjCInstanceTypeFamily OIT_Family = OIT_None);
65 
66   void migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl);
67   void AddCFAnnotations(ASTContext &Ctx, const CallEffects &CE,
68                         const FunctionDecl *FuncDecl, bool ResultAnnotated);
69   void AddCFAnnotations(ASTContext &Ctx, const CallEffects &CE,
70                         const ObjCMethodDecl *MethodDecl, bool ResultAnnotated);
71 
72   void AnnotateImplicitBridging(ASTContext &Ctx);
73 
74   CF_BRIDGING_KIND migrateAddFunctionAnnotation(ASTContext &Ctx,
75                                                 const FunctionDecl *FuncDecl);
76 
77   void migrateARCSafeAnnotation(ASTContext &Ctx, ObjCContainerDecl *CDecl);
78 
79   void migrateAddMethodAnnotation(ASTContext &Ctx,
80                                   const ObjCMethodDecl *MethodDecl);
81 
82   void inferDesignatedInitializers(ASTContext &Ctx,
83                                    const ObjCImplementationDecl *ImplD);
84 
85 public:
86   std::string MigrateDir;
87   unsigned ASTMigrateActions;
88   FileID FileId;
89   const TypedefDecl *NSIntegerTypedefed;
90   const TypedefDecl *NSUIntegerTypedefed;
91   std::unique_ptr<NSAPI> NSAPIObj;
92   std::unique_ptr<edit::EditedSource> Editor;
93   FileRemapper &Remapper;
94   FileManager &FileMgr;
95   const PPConditionalDirectiveRecord *PPRec;
96   Preprocessor &PP;
97   bool IsOutputFile;
98   llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ObjCProtocolDecls;
99   llvm::SmallVector<const Decl *, 8> CFFunctionIBCandidates;
100   llvm::StringMap<char> WhiteListFilenames;
101 
102   ObjCMigrateASTConsumer(StringRef migrateDir,
103                          unsigned astMigrateActions,
104                          FileRemapper &remapper,
105                          FileManager &fileMgr,
106                          const PPConditionalDirectiveRecord *PPRec,
107                          Preprocessor &PP,
108                          bool isOutputFile,
109                          ArrayRef<std::string> WhiteList)
110   : MigrateDir(migrateDir),
111     ASTMigrateActions(astMigrateActions),
112     NSIntegerTypedefed(nullptr), NSUIntegerTypedefed(nullptr),
113     Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP),
114     IsOutputFile(isOutputFile) {
115 
116     for (ArrayRef<std::string>::iterator
117            I = WhiteList.begin(), E = WhiteList.end(); I != E; ++I) {
118       WhiteListFilenames.GetOrCreateValue(*I);
119     }
120   }
121 
122 protected:
123   void Initialize(ASTContext &Context) override {
124     NSAPIObj.reset(new NSAPI(Context));
125     Editor.reset(new edit::EditedSource(Context.getSourceManager(),
126                                         Context.getLangOpts(),
127                                         PPRec));
128   }
129 
130   bool HandleTopLevelDecl(DeclGroupRef DG) override {
131     for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
132       migrateDecl(*I);
133     return true;
134   }
135   void HandleInterestingDecl(DeclGroupRef DG) override {
136     // Ignore decls from the PCH.
137   }
138   void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override {
139     ObjCMigrateASTConsumer::HandleTopLevelDecl(DG);
140   }
141 
142   void HandleTranslationUnit(ASTContext &Ctx) override;
143 
144   bool canModifyFile(StringRef Path) {
145     if (WhiteListFilenames.empty())
146       return true;
147     return WhiteListFilenames.find(llvm::sys::path::filename(Path))
148         != WhiteListFilenames.end();
149   }
150   bool canModifyFile(const FileEntry *FE) {
151     if (!FE)
152       return false;
153     return canModifyFile(FE->getName());
154   }
155   bool canModifyFile(FileID FID) {
156     if (FID.isInvalid())
157       return false;
158     return canModifyFile(PP.getSourceManager().getFileEntryForID(FID));
159   }
160 
161   bool canModify(const Decl *D) {
162     if (!D)
163       return false;
164     if (const ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(D))
165       return canModify(CatImpl->getCategoryDecl());
166     if (const ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D))
167       return canModify(Impl->getClassInterface());
168     if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
169       return canModify(cast<Decl>(MD->getDeclContext()));
170 
171     FileID FID = PP.getSourceManager().getFileID(D->getLocation());
172     return canModifyFile(FID);
173   }
174 };
175 
176 }
177 
178 ObjCMigrateAction::ObjCMigrateAction(FrontendAction *WrappedAction,
179                                      StringRef migrateDir,
180                                      unsigned migrateAction)
181   : WrapperFrontendAction(WrappedAction), MigrateDir(migrateDir),
182     ObjCMigAction(migrateAction),
183     CompInst(nullptr) {
184   if (MigrateDir.empty())
185     MigrateDir = "."; // user current directory if none is given.
186 }
187 
188 std::unique_ptr<ASTConsumer>
189 ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
190   PPConditionalDirectiveRecord *
191     PPRec = new PPConditionalDirectiveRecord(CompInst->getSourceManager());
192   CompInst->getPreprocessor().addPPCallbacks(PPRec);
193   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
194   Consumers.push_back(WrapperFrontendAction::CreateASTConsumer(CI, InFile));
195   Consumers.push_back(llvm::make_unique<ObjCMigrateASTConsumer>(
196       MigrateDir, ObjCMigAction, Remapper, CompInst->getFileManager(), PPRec,
197       CompInst->getPreprocessor(), false, ArrayRef<std::string>()));
198   return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
199 }
200 
201 bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) {
202   Remapper.initFromDisk(MigrateDir, CI.getDiagnostics(),
203                         /*ignoreIfFilesChanges=*/true);
204   CompInst = &CI;
205   CI.getDiagnostics().setIgnoreAllWarnings(true);
206   return true;
207 }
208 
209 namespace {
210 class ObjCMigrator : public RecursiveASTVisitor<ObjCMigrator> {
211   ObjCMigrateASTConsumer &Consumer;
212   ParentMap &PMap;
213 
214 public:
215   ObjCMigrator(ObjCMigrateASTConsumer &consumer, ParentMap &PMap)
216     : Consumer(consumer), PMap(PMap) { }
217 
218   bool shouldVisitTemplateInstantiations() const { return false; }
219   bool shouldWalkTypesOfTypeLocs() const { return false; }
220 
221   bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
222     if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Literals) {
223       edit::Commit commit(*Consumer.Editor);
224       edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit, &PMap);
225       Consumer.Editor->commit(commit);
226     }
227 
228     if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Subscripting) {
229       edit::Commit commit(*Consumer.Editor);
230       edit::rewriteToObjCSubscriptSyntax(E, *Consumer.NSAPIObj, commit);
231       Consumer.Editor->commit(commit);
232     }
233 
234     return true;
235   }
236 
237   bool TraverseObjCMessageExpr(ObjCMessageExpr *E) {
238     // Do depth first; we want to rewrite the subexpressions first so that if
239     // we have to move expressions we will move them already rewritten.
240     for (Stmt::child_range range = E->children(); range; ++range)
241       if (!TraverseStmt(*range))
242         return false;
243 
244     return WalkUpFromObjCMessageExpr(E);
245   }
246 };
247 
248 class BodyMigrator : public RecursiveASTVisitor<BodyMigrator> {
249   ObjCMigrateASTConsumer &Consumer;
250   std::unique_ptr<ParentMap> PMap;
251 
252 public:
253   BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { }
254 
255   bool shouldVisitTemplateInstantiations() const { return false; }
256   bool shouldWalkTypesOfTypeLocs() const { return false; }
257 
258   bool TraverseStmt(Stmt *S) {
259     PMap.reset(new ParentMap(S));
260     ObjCMigrator(Consumer, *PMap).TraverseStmt(S);
261     return true;
262   }
263 };
264 }
265 
266 void ObjCMigrateASTConsumer::migrateDecl(Decl *D) {
267   if (!D)
268     return;
269   if (isa<ObjCMethodDecl>(D))
270     return; // Wait for the ObjC container declaration.
271 
272   BodyMigrator(*this).TraverseDecl(D);
273 }
274 
275 static void append_attr(std::string &PropertyString, const char *attr,
276                         bool &LParenAdded) {
277   if (!LParenAdded) {
278     PropertyString += "(";
279     LParenAdded = true;
280   }
281   else
282     PropertyString += ", ";
283   PropertyString += attr;
284 }
285 
286 static
287 void MigrateBlockOrFunctionPointerTypeVariable(std::string & PropertyString,
288                                                const std::string& TypeString,
289                                                const char *name) {
290   const char *argPtr = TypeString.c_str();
291   int paren = 0;
292   while (*argPtr) {
293     switch (*argPtr) {
294       case '(':
295         PropertyString += *argPtr;
296         paren++;
297         break;
298       case ')':
299         PropertyString += *argPtr;
300         paren--;
301         break;
302       case '^':
303       case '*':
304         PropertyString += (*argPtr);
305         if (paren == 1) {
306           PropertyString += name;
307           name = "";
308         }
309         break;
310       default:
311         PropertyString += *argPtr;
312         break;
313     }
314     argPtr++;
315   }
316 }
317 
318 static const char *PropertyMemoryAttribute(ASTContext &Context, QualType ArgType) {
319   Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime();
320   bool RetainableObject = ArgType->isObjCRetainableType();
321   if (RetainableObject &&
322       (propertyLifetime == Qualifiers::OCL_Strong
323        || propertyLifetime == Qualifiers::OCL_None)) {
324     if (const ObjCObjectPointerType *ObjPtrTy =
325         ArgType->getAs<ObjCObjectPointerType>()) {
326       ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
327       if (IDecl &&
328           IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying")))
329         return "copy";
330       else
331         return "strong";
332     }
333     else if (ArgType->isBlockPointerType())
334       return "copy";
335   } else if (propertyLifetime == Qualifiers::OCL_Weak)
336     // TODO. More precise determination of 'weak' attribute requires
337     // looking into setter's implementation for backing weak ivar.
338     return "weak";
339   else if (RetainableObject)
340     return ArgType->isBlockPointerType() ? "copy" : "strong";
341   return nullptr;
342 }
343 
344 static void rewriteToObjCProperty(const ObjCMethodDecl *Getter,
345                                   const ObjCMethodDecl *Setter,
346                                   const NSAPI &NS, edit::Commit &commit,
347                                   unsigned LengthOfPrefix,
348                                   bool Atomic, bool UseNsIosOnlyMacro,
349                                   bool AvailabilityArgsMatch) {
350   ASTContext &Context = NS.getASTContext();
351   bool LParenAdded = false;
352   std::string PropertyString = "@property ";
353   if (UseNsIosOnlyMacro && Context.Idents.get("NS_NONATOMIC_IOSONLY").hasMacroDefinition()) {
354     PropertyString += "(NS_NONATOMIC_IOSONLY";
355     LParenAdded = true;
356   } else if (!Atomic) {
357     PropertyString += "(nonatomic";
358     LParenAdded = true;
359   }
360 
361   std::string PropertyNameString = Getter->getNameAsString();
362   StringRef PropertyName(PropertyNameString);
363   if (LengthOfPrefix > 0) {
364     if (!LParenAdded) {
365       PropertyString += "(getter=";
366       LParenAdded = true;
367     }
368     else
369       PropertyString += ", getter=";
370     PropertyString += PropertyNameString;
371   }
372   // Property with no setter may be suggested as a 'readonly' property.
373   if (!Setter)
374     append_attr(PropertyString, "readonly", LParenAdded);
375 
376 
377   // Short circuit 'delegate' properties that contain the name "delegate" or
378   // "dataSource", or have exact name "target" to have 'assign' attribute.
379   if (PropertyName.equals("target") ||
380       (PropertyName.find("delegate") != StringRef::npos) ||
381       (PropertyName.find("dataSource") != StringRef::npos)) {
382     QualType QT = Getter->getReturnType();
383     if (!QT->isRealType())
384       append_attr(PropertyString, "assign", LParenAdded);
385   } else if (!Setter) {
386     QualType ResType = Context.getCanonicalType(Getter->getReturnType());
387     if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ResType))
388       append_attr(PropertyString, MemoryManagementAttr, LParenAdded);
389   } else {
390     const ParmVarDecl *argDecl = *Setter->param_begin();
391     QualType ArgType = Context.getCanonicalType(argDecl->getType());
392     if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ArgType))
393       append_attr(PropertyString, MemoryManagementAttr, LParenAdded);
394   }
395   if (LParenAdded)
396     PropertyString += ')';
397   QualType RT = Getter->getReturnType();
398   if (!isa<TypedefType>(RT)) {
399     // strip off any ARC lifetime qualifier.
400     QualType CanResultTy = Context.getCanonicalType(RT);
401     if (CanResultTy.getQualifiers().hasObjCLifetime()) {
402       Qualifiers Qs = CanResultTy.getQualifiers();
403       Qs.removeObjCLifetime();
404       RT = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs);
405     }
406   }
407   PropertyString += " ";
408   PrintingPolicy SubPolicy(Context.getPrintingPolicy());
409   SubPolicy.SuppressStrongLifetime = true;
410   SubPolicy.SuppressLifetimeQualifiers = true;
411   std::string TypeString = RT.getAsString(SubPolicy);
412   if (LengthOfPrefix > 0) {
413     // property name must strip off "is" and lower case the first character
414     // after that; e.g. isContinuous will become continuous.
415     StringRef PropertyNameStringRef(PropertyNameString);
416     PropertyNameStringRef = PropertyNameStringRef.drop_front(LengthOfPrefix);
417     PropertyNameString = PropertyNameStringRef;
418     bool NoLowering = (isUppercase(PropertyNameString[0]) &&
419                        PropertyNameString.size() > 1 &&
420                        isUppercase(PropertyNameString[1]));
421     if (!NoLowering)
422       PropertyNameString[0] = toLowercase(PropertyNameString[0]);
423   }
424   if (RT->isBlockPointerType() || RT->isFunctionPointerType())
425     MigrateBlockOrFunctionPointerTypeVariable(PropertyString,
426                                               TypeString,
427                                               PropertyNameString.c_str());
428   else {
429     char LastChar = TypeString[TypeString.size()-1];
430     PropertyString += TypeString;
431     if (LastChar != '*')
432       PropertyString += ' ';
433     PropertyString += PropertyNameString;
434   }
435   SourceLocation StartGetterSelectorLoc = Getter->getSelectorStartLoc();
436   Selector GetterSelector = Getter->getSelector();
437 
438   SourceLocation EndGetterSelectorLoc =
439     StartGetterSelectorLoc.getLocWithOffset(GetterSelector.getNameForSlot(0).size());
440   commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(),
441                                                EndGetterSelectorLoc),
442                  PropertyString);
443   if (Setter && AvailabilityArgsMatch) {
444     SourceLocation EndLoc = Setter->getDeclaratorEndLoc();
445     // Get location past ';'
446     EndLoc = EndLoc.getLocWithOffset(1);
447     SourceLocation BeginOfSetterDclLoc = Setter->getLocStart();
448     // FIXME. This assumes that setter decl; is immediately preceded by eoln.
449     // It is trying to remove the setter method decl. line entirely.
450     BeginOfSetterDclLoc = BeginOfSetterDclLoc.getLocWithOffset(-1);
451     commit.remove(SourceRange(BeginOfSetterDclLoc, EndLoc));
452   }
453 }
454 
455 static bool IsCategoryNameWithDeprecatedSuffix(ObjCContainerDecl *D) {
456   if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(D)) {
457     StringRef Name = CatDecl->getName();
458     return Name.endswith("Deprecated");
459   }
460   return false;
461 }
462 
463 void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx,
464                                                       ObjCContainerDecl *D) {
465   if (D->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(D))
466     return;
467 
468   for (auto *Method : D->methods()) {
469     if (Method->isDeprecated())
470       continue;
471     bool PropertyInferred = migrateProperty(Ctx, D, Method);
472     // If a property is inferred, do not attempt to attach NS_RETURNS_INNER_POINTER to
473     // the getter method as it ends up on the property itself which we don't want
474     // to do unless -objcmt-returns-innerpointer-property  option is on.
475     if (!PropertyInferred ||
476         (ASTMigrateActions & FrontendOptions::ObjCMT_ReturnsInnerPointerProperty))
477       if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
478         migrateNsReturnsInnerPointer(Ctx, Method);
479   }
480   if (!(ASTMigrateActions & FrontendOptions::ObjCMT_ReturnsInnerPointerProperty))
481     return;
482 
483   for (auto *Prop : D->properties()) {
484     if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
485         !Prop->isDeprecated())
486       migratePropertyNsReturnsInnerPointer(Ctx, Prop);
487   }
488 }
489 
490 static bool
491 ClassImplementsAllMethodsAndProperties(ASTContext &Ctx,
492                                       const ObjCImplementationDecl *ImpDecl,
493                                        const ObjCInterfaceDecl *IDecl,
494                                       ObjCProtocolDecl *Protocol) {
495   // In auto-synthesis, protocol properties are not synthesized. So,
496   // a conforming protocol must have its required properties declared
497   // in class interface.
498   bool HasAtleastOneRequiredProperty = false;
499   if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition())
500     for (const auto *Property : PDecl->properties()) {
501       if (Property->getPropertyImplementation() == ObjCPropertyDecl::Optional)
502         continue;
503       HasAtleastOneRequiredProperty = true;
504       DeclContext::lookup_const_result R = IDecl->lookup(Property->getDeclName());
505       if (R.size() == 0) {
506         // Relax the rule and look into class's implementation for a synthesize
507         // or dynamic declaration. Class is implementing a property coming from
508         // another protocol. This still makes the target protocol as conforming.
509         if (!ImpDecl->FindPropertyImplDecl(
510                                   Property->getDeclName().getAsIdentifierInfo()))
511           return false;
512       }
513       else if (ObjCPropertyDecl *ClassProperty = dyn_cast<ObjCPropertyDecl>(R[0])) {
514           if ((ClassProperty->getPropertyAttributes()
515               != Property->getPropertyAttributes()) ||
516               !Ctx.hasSameType(ClassProperty->getType(), Property->getType()))
517             return false;
518       }
519       else
520         return false;
521     }
522 
523   // At this point, all required properties in this protocol conform to those
524   // declared in the class.
525   // Check that class implements the required methods of the protocol too.
526   bool HasAtleastOneRequiredMethod = false;
527   if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) {
528     if (PDecl->meth_begin() == PDecl->meth_end())
529       return HasAtleastOneRequiredProperty;
530     for (const auto *MD : PDecl->methods()) {
531       if (MD->isImplicit())
532         continue;
533       if (MD->getImplementationControl() == ObjCMethodDecl::Optional)
534         continue;
535       DeclContext::lookup_const_result R = ImpDecl->lookup(MD->getDeclName());
536       if (R.size() == 0)
537         return false;
538       bool match = false;
539       HasAtleastOneRequiredMethod = true;
540       for (unsigned I = 0, N = R.size(); I != N; ++I)
541         if (ObjCMethodDecl *ImpMD = dyn_cast<ObjCMethodDecl>(R[0]))
542           if (Ctx.ObjCMethodsAreEqual(MD, ImpMD)) {
543             match = true;
544             break;
545           }
546       if (!match)
547         return false;
548     }
549   }
550   if (HasAtleastOneRequiredProperty || HasAtleastOneRequiredMethod)
551     return true;
552   return false;
553 }
554 
555 static bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl,
556                     llvm::SmallVectorImpl<ObjCProtocolDecl*> &ConformingProtocols,
557                     const NSAPI &NS, edit::Commit &commit) {
558   const ObjCList<ObjCProtocolDecl> &Protocols = IDecl->getReferencedProtocols();
559   std::string ClassString;
560   SourceLocation EndLoc =
561   IDecl->getSuperClass() ? IDecl->getSuperClassLoc() : IDecl->getLocation();
562 
563   if (Protocols.empty()) {
564     ClassString = '<';
565     for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
566       ClassString += ConformingProtocols[i]->getNameAsString();
567       if (i != (e-1))
568         ClassString += ", ";
569     }
570     ClassString += "> ";
571   }
572   else {
573     ClassString = ", ";
574     for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
575       ClassString += ConformingProtocols[i]->getNameAsString();
576       if (i != (e-1))
577         ClassString += ", ";
578     }
579     ObjCInterfaceDecl::protocol_loc_iterator PL = IDecl->protocol_loc_end() - 1;
580     EndLoc = *PL;
581   }
582 
583   commit.insertAfterToken(EndLoc, ClassString);
584   return true;
585 }
586 
587 static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
588                                 const TypedefDecl *TypedefDcl,
589                                 const NSAPI &NS, edit::Commit &commit,
590                                 bool IsNSIntegerType,
591                                 bool NSOptions) {
592   std::string ClassString;
593   if (NSOptions)
594     ClassString = "typedef NS_OPTIONS(NSUInteger, ";
595   else
596     ClassString =
597       IsNSIntegerType ? "typedef NS_ENUM(NSInteger, "
598                       : "typedef NS_ENUM(NSUInteger, ";
599 
600   ClassString += TypedefDcl->getIdentifier()->getName();
601   ClassString += ')';
602   SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart());
603   commit.replace(R, ClassString);
604   SourceLocation EndOfEnumDclLoc = EnumDcl->getLocEnd();
605   EndOfEnumDclLoc = trans::findSemiAfterLocation(EndOfEnumDclLoc,
606                                                  NS.getASTContext(), /*IsDecl*/true);
607   if (!EndOfEnumDclLoc.isInvalid()) {
608     SourceRange EnumDclRange(EnumDcl->getLocStart(), EndOfEnumDclLoc);
609     commit.insertFromRange(TypedefDcl->getLocStart(), EnumDclRange);
610   }
611   else
612     return false;
613 
614   SourceLocation EndTypedefDclLoc = TypedefDcl->getLocEnd();
615   EndTypedefDclLoc = trans::findSemiAfterLocation(EndTypedefDclLoc,
616                                                  NS.getASTContext(), /*IsDecl*/true);
617   if (!EndTypedefDclLoc.isInvalid()) {
618     SourceRange TDRange(TypedefDcl->getLocStart(), EndTypedefDclLoc);
619     commit.remove(TDRange);
620   }
621   else
622     return false;
623 
624   EndOfEnumDclLoc = trans::findLocationAfterSemi(EnumDcl->getLocEnd(), NS.getASTContext(),
625                                                  /*IsDecl*/true);
626   if (!EndOfEnumDclLoc.isInvalid()) {
627     SourceLocation BeginOfEnumDclLoc = EnumDcl->getLocStart();
628     // FIXME. This assumes that enum decl; is immediately preceded by eoln.
629     // It is trying to remove the enum decl. lines entirely.
630     BeginOfEnumDclLoc = BeginOfEnumDclLoc.getLocWithOffset(-1);
631     commit.remove(SourceRange(BeginOfEnumDclLoc, EndOfEnumDclLoc));
632     return true;
633   }
634   return false;
635 }
636 
637 static void rewriteToNSMacroDecl(const EnumDecl *EnumDcl,
638                                 const TypedefDecl *TypedefDcl,
639                                 const NSAPI &NS, edit::Commit &commit,
640                                  bool IsNSIntegerType) {
641   std::string ClassString =
642     IsNSIntegerType ? "NS_ENUM(NSInteger, " : "NS_OPTIONS(NSUInteger, ";
643   ClassString += TypedefDcl->getIdentifier()->getName();
644   ClassString += ')';
645   SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart());
646   commit.replace(R, ClassString);
647   SourceLocation TypedefLoc = TypedefDcl->getLocEnd();
648   commit.remove(SourceRange(TypedefLoc, TypedefLoc));
649 }
650 
651 static bool UseNSOptionsMacro(Preprocessor &PP, ASTContext &Ctx,
652                               const EnumDecl *EnumDcl) {
653   bool PowerOfTwo = true;
654   bool AllHexdecimalEnumerator = true;
655   uint64_t MaxPowerOfTwoVal = 0;
656   for (auto Enumerator : EnumDcl->enumerators()) {
657     const Expr *InitExpr = Enumerator->getInitExpr();
658     if (!InitExpr) {
659       PowerOfTwo = false;
660       AllHexdecimalEnumerator = false;
661       continue;
662     }
663     InitExpr = InitExpr->IgnoreParenCasts();
664     if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(InitExpr))
665       if (BO->isShiftOp() || BO->isBitwiseOp())
666         return true;
667 
668     uint64_t EnumVal = Enumerator->getInitVal().getZExtValue();
669     if (PowerOfTwo && EnumVal) {
670       if (!llvm::isPowerOf2_64(EnumVal))
671         PowerOfTwo = false;
672       else if (EnumVal > MaxPowerOfTwoVal)
673         MaxPowerOfTwoVal = EnumVal;
674     }
675     if (AllHexdecimalEnumerator && EnumVal) {
676       bool FoundHexdecimalEnumerator = false;
677       SourceLocation EndLoc = Enumerator->getLocEnd();
678       Token Tok;
679       if (!PP.getRawToken(EndLoc, Tok, /*IgnoreWhiteSpace=*/true))
680         if (Tok.isLiteral() && Tok.getLength() > 2) {
681           if (const char *StringLit = Tok.getLiteralData())
682             FoundHexdecimalEnumerator =
683               (StringLit[0] == '0' && (toLowercase(StringLit[1]) == 'x'));
684         }
685       if (!FoundHexdecimalEnumerator)
686         AllHexdecimalEnumerator = false;
687     }
688   }
689   return AllHexdecimalEnumerator || (PowerOfTwo && (MaxPowerOfTwoVal > 2));
690 }
691 
692 void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx,
693                                             const ObjCImplementationDecl *ImpDecl) {
694   const ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface();
695   if (!IDecl || ObjCProtocolDecls.empty() || IDecl->isDeprecated())
696     return;
697   // Find all implicit conforming protocols for this class
698   // and make them explicit.
699   llvm::SmallPtrSet<ObjCProtocolDecl *, 8> ExplicitProtocols;
700   Ctx.CollectInheritedProtocols(IDecl, ExplicitProtocols);
701   llvm::SmallVector<ObjCProtocolDecl *, 8> PotentialImplicitProtocols;
702 
703   for (llvm::SmallPtrSet<ObjCProtocolDecl*, 32>::iterator I =
704        ObjCProtocolDecls.begin(),
705        E = ObjCProtocolDecls.end(); I != E; ++I)
706     if (!ExplicitProtocols.count(*I))
707       PotentialImplicitProtocols.push_back(*I);
708 
709   if (PotentialImplicitProtocols.empty())
710     return;
711 
712   // go through list of non-optional methods and properties in each protocol
713   // in the PotentialImplicitProtocols list. If class implements every one of the
714   // methods and properties, then this class conforms to this protocol.
715   llvm::SmallVector<ObjCProtocolDecl*, 8> ConformingProtocols;
716   for (unsigned i = 0, e = PotentialImplicitProtocols.size(); i != e; i++)
717     if (ClassImplementsAllMethodsAndProperties(Ctx, ImpDecl, IDecl,
718                                               PotentialImplicitProtocols[i]))
719       ConformingProtocols.push_back(PotentialImplicitProtocols[i]);
720 
721   if (ConformingProtocols.empty())
722     return;
723 
724   // Further reduce number of conforming protocols. If protocol P1 is in the list
725   // protocol P2 (P2<P1>), No need to include P1.
726   llvm::SmallVector<ObjCProtocolDecl*, 8> MinimalConformingProtocols;
727   for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
728     bool DropIt = false;
729     ObjCProtocolDecl *TargetPDecl = ConformingProtocols[i];
730     for (unsigned i1 = 0, e1 = ConformingProtocols.size(); i1 != e1; i1++) {
731       ObjCProtocolDecl *PDecl = ConformingProtocols[i1];
732       if (PDecl == TargetPDecl)
733         continue;
734       if (PDecl->lookupProtocolNamed(
735             TargetPDecl->getDeclName().getAsIdentifierInfo())) {
736         DropIt = true;
737         break;
738       }
739     }
740     if (!DropIt)
741       MinimalConformingProtocols.push_back(TargetPDecl);
742   }
743   if (MinimalConformingProtocols.empty())
744     return;
745   edit::Commit commit(*Editor);
746   rewriteToObjCInterfaceDecl(IDecl, MinimalConformingProtocols,
747                              *NSAPIObj, commit);
748   Editor->commit(commit);
749 }
750 
751 void ObjCMigrateASTConsumer::CacheObjCNSIntegerTypedefed(
752                                           const TypedefDecl *TypedefDcl) {
753 
754   QualType qt = TypedefDcl->getTypeSourceInfo()->getType();
755   if (NSAPIObj->isObjCNSIntegerType(qt))
756     NSIntegerTypedefed = TypedefDcl;
757   else if (NSAPIObj->isObjCNSUIntegerType(qt))
758     NSUIntegerTypedefed = TypedefDcl;
759 }
760 
761 bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
762                                            const EnumDecl *EnumDcl,
763                                            const TypedefDecl *TypedefDcl) {
764   if (!EnumDcl->isCompleteDefinition() || EnumDcl->getIdentifier() ||
765       EnumDcl->isDeprecated())
766     return false;
767   if (!TypedefDcl) {
768     if (NSIntegerTypedefed) {
769       TypedefDcl = NSIntegerTypedefed;
770       NSIntegerTypedefed = nullptr;
771     }
772     else if (NSUIntegerTypedefed) {
773       TypedefDcl = NSUIntegerTypedefed;
774       NSUIntegerTypedefed = nullptr;
775     }
776     else
777       return false;
778     FileID FileIdOfTypedefDcl =
779       PP.getSourceManager().getFileID(TypedefDcl->getLocation());
780     FileID FileIdOfEnumDcl =
781       PP.getSourceManager().getFileID(EnumDcl->getLocation());
782     if (FileIdOfTypedefDcl != FileIdOfEnumDcl)
783       return false;
784   }
785   if (TypedefDcl->isDeprecated())
786     return false;
787 
788   QualType qt = TypedefDcl->getTypeSourceInfo()->getType();
789   bool IsNSIntegerType = NSAPIObj->isObjCNSIntegerType(qt);
790   bool IsNSUIntegerType = !IsNSIntegerType && NSAPIObj->isObjCNSUIntegerType(qt);
791 
792   if (!IsNSIntegerType && !IsNSUIntegerType) {
793     // Also check for typedef enum {...} TD;
794     if (const EnumType *EnumTy = qt->getAs<EnumType>()) {
795       if (EnumTy->getDecl() == EnumDcl) {
796         bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl);
797         if (NSOptions) {
798           if (!Ctx.Idents.get("NS_OPTIONS").hasMacroDefinition())
799             return false;
800         }
801         else if (!Ctx.Idents.get("NS_ENUM").hasMacroDefinition())
802           return false;
803         edit::Commit commit(*Editor);
804         rewriteToNSMacroDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit, !NSOptions);
805         Editor->commit(commit);
806         return true;
807       }
808     }
809     return false;
810   }
811 
812   // We may still use NS_OPTIONS based on what we find in the enumertor list.
813   bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl);
814   // NS_ENUM must be available.
815   if (IsNSIntegerType && !Ctx.Idents.get("NS_ENUM").hasMacroDefinition())
816     return false;
817   // NS_OPTIONS must be available.
818   if (IsNSUIntegerType && !Ctx.Idents.get("NS_OPTIONS").hasMacroDefinition())
819     return false;
820   edit::Commit commit(*Editor);
821   bool Res = rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj,
822                                  commit, IsNSIntegerType, NSOptions);
823   Editor->commit(commit);
824   return Res;
825 }
826 
827 static void ReplaceWithInstancetype(ASTContext &Ctx,
828                                     const ObjCMigrateASTConsumer &ASTC,
829                                     ObjCMethodDecl *OM) {
830   if (OM->getReturnType() == Ctx.getObjCInstanceType())
831     return; // already has instancetype.
832 
833   SourceRange R;
834   std::string ClassString;
835   if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) {
836     TypeLoc TL = TSInfo->getTypeLoc();
837     R = SourceRange(TL.getBeginLoc(), TL.getEndLoc());
838     ClassString = "instancetype";
839   }
840   else {
841     R = SourceRange(OM->getLocStart(), OM->getLocStart());
842     ClassString = OM->isInstanceMethod() ? '-' : '+';
843     ClassString += " (instancetype)";
844   }
845   edit::Commit commit(*ASTC.Editor);
846   commit.replace(R, ClassString);
847   ASTC.Editor->commit(commit);
848 }
849 
850 static void ReplaceWithClasstype(const ObjCMigrateASTConsumer &ASTC,
851                                     ObjCMethodDecl *OM) {
852   ObjCInterfaceDecl *IDecl = OM->getClassInterface();
853   SourceRange R;
854   std::string ClassString;
855   if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) {
856     TypeLoc TL = TSInfo->getTypeLoc();
857     R = SourceRange(TL.getBeginLoc(), TL.getEndLoc()); {
858       ClassString  = IDecl->getName();
859       ClassString += "*";
860     }
861   }
862   else {
863     R = SourceRange(OM->getLocStart(), OM->getLocStart());
864     ClassString = "+ (";
865     ClassString += IDecl->getName(); ClassString += "*)";
866   }
867   edit::Commit commit(*ASTC.Editor);
868   commit.replace(R, ClassString);
869   ASTC.Editor->commit(commit);
870 }
871 
872 void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx,
873                                                        ObjCContainerDecl *CDecl,
874                                                        ObjCMethodDecl *OM) {
875   ObjCInstanceTypeFamily OIT_Family =
876     Selector::getInstTypeMethodFamily(OM->getSelector());
877 
878   std::string ClassName;
879   switch (OIT_Family) {
880     case OIT_None:
881       migrateFactoryMethod(Ctx, CDecl, OM);
882       return;
883     case OIT_Array:
884       ClassName = "NSArray";
885       break;
886     case OIT_Dictionary:
887       ClassName = "NSDictionary";
888       break;
889     case OIT_Singleton:
890       migrateFactoryMethod(Ctx, CDecl, OM, OIT_Singleton);
891       return;
892     case OIT_Init:
893       if (OM->getReturnType()->isObjCIdType())
894         ReplaceWithInstancetype(Ctx, *this, OM);
895       return;
896     case OIT_ReturnsSelf:
897       migrateFactoryMethod(Ctx, CDecl, OM, OIT_ReturnsSelf);
898       return;
899   }
900   if (!OM->getReturnType()->isObjCIdType())
901     return;
902 
903   ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
904   if (!IDecl) {
905     if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
906       IDecl = CatDecl->getClassInterface();
907     else if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(CDecl))
908       IDecl = ImpDecl->getClassInterface();
909   }
910   if (!IDecl ||
911       !IDecl->lookupInheritedClass(&Ctx.Idents.get(ClassName))) {
912     migrateFactoryMethod(Ctx, CDecl, OM);
913     return;
914   }
915   ReplaceWithInstancetype(Ctx, *this, OM);
916 }
917 
918 static bool TypeIsInnerPointer(QualType T) {
919   if (!T->isAnyPointerType())
920     return false;
921   if (T->isObjCObjectPointerType() || T->isObjCBuiltinType() ||
922       T->isBlockPointerType() || T->isFunctionPointerType() ||
923       ento::coreFoundation::isCFObjectRef(T))
924     return false;
925   // Also, typedef-of-pointer-to-incomplete-struct is something that we assume
926   // is not an innter pointer type.
927   QualType OrigT = T;
928   while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr()))
929     T = TD->getDecl()->getUnderlyingType();
930   if (OrigT == T || !T->isPointerType())
931     return true;
932   const PointerType* PT = T->getAs<PointerType>();
933   QualType UPointeeT = PT->getPointeeType().getUnqualifiedType();
934   if (UPointeeT->isRecordType()) {
935     const RecordType *RecordTy = UPointeeT->getAs<RecordType>();
936     if (!RecordTy->getDecl()->isCompleteDefinition())
937       return false;
938   }
939   return true;
940 }
941 
942 /// \brief Check whether the two versions match.
943 static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y) {
944   return (X == Y);
945 }
946 
947 /// AvailabilityAttrsMatch - This routine checks that if comparing two
948 /// availability attributes, all their components match. It returns
949 /// true, if not dealing with availability or when all components of
950 /// availability attributes match. This routine is only called when
951 /// the attributes are of the same kind.
952 static bool AvailabilityAttrsMatch(Attr *At1, Attr *At2) {
953   const AvailabilityAttr *AA1 = dyn_cast<AvailabilityAttr>(At1);
954   if (!AA1)
955     return true;
956   const AvailabilityAttr *AA2 = dyn_cast<AvailabilityAttr>(At2);
957 
958   VersionTuple Introduced1 = AA1->getIntroduced();
959   VersionTuple Deprecated1 = AA1->getDeprecated();
960   VersionTuple Obsoleted1 = AA1->getObsoleted();
961   bool IsUnavailable1 = AA1->getUnavailable();
962   VersionTuple Introduced2 = AA2->getIntroduced();
963   VersionTuple Deprecated2 = AA2->getDeprecated();
964   VersionTuple Obsoleted2 = AA2->getObsoleted();
965   bool IsUnavailable2 = AA2->getUnavailable();
966   return (versionsMatch(Introduced1, Introduced2) &&
967           versionsMatch(Deprecated1, Deprecated2) &&
968           versionsMatch(Obsoleted1, Obsoleted2) &&
969           IsUnavailable1 == IsUnavailable2);
970 
971 }
972 
973 static bool MatchTwoAttributeLists(const AttrVec &Attrs1, const AttrVec &Attrs2,
974                                    bool &AvailabilityArgsMatch) {
975   // This list is very small, so this need not be optimized.
976   for (unsigned i = 0, e = Attrs1.size(); i != e; i++) {
977     bool match = false;
978     for (unsigned j = 0, f = Attrs2.size(); j != f; j++) {
979       // Matching attribute kind only. Except for Availabilty attributes,
980       // we are not getting into details of the attributes. For all practical purposes
981       // this is sufficient.
982       if (Attrs1[i]->getKind() == Attrs2[j]->getKind()) {
983         if (AvailabilityArgsMatch)
984           AvailabilityArgsMatch = AvailabilityAttrsMatch(Attrs1[i], Attrs2[j]);
985         match = true;
986         break;
987       }
988     }
989     if (!match)
990       return false;
991   }
992   return true;
993 }
994 
995 /// AttributesMatch - This routine checks list of attributes for two
996 /// decls. It returns false, if there is a mismatch in kind of
997 /// attributes seen in the decls. It returns true if the two decls
998 /// have list of same kind of attributes. Furthermore, when there
999 /// are availability attributes in the two decls, it sets the
1000 /// AvailabilityArgsMatch to false if availability attributes have
1001 /// different versions, etc.
1002 static bool AttributesMatch(const Decl *Decl1, const Decl *Decl2,
1003                             bool &AvailabilityArgsMatch) {
1004   if (!Decl1->hasAttrs() || !Decl2->hasAttrs()) {
1005     AvailabilityArgsMatch = (Decl1->hasAttrs() == Decl2->hasAttrs());
1006     return true;
1007   }
1008   AvailabilityArgsMatch = true;
1009   const AttrVec &Attrs1 = Decl1->getAttrs();
1010   const AttrVec &Attrs2 = Decl2->getAttrs();
1011   bool match = MatchTwoAttributeLists(Attrs1, Attrs2, AvailabilityArgsMatch);
1012   if (match && (Attrs2.size() > Attrs1.size()))
1013     return MatchTwoAttributeLists(Attrs2, Attrs1, AvailabilityArgsMatch);
1014   return match;
1015 }
1016 
1017 static bool IsValidIdentifier(ASTContext &Ctx,
1018                               const char *Name) {
1019   if (!isIdentifierHead(Name[0]))
1020     return false;
1021   std::string NameString = Name;
1022   NameString[0] = toLowercase(NameString[0]);
1023   IdentifierInfo *II = &Ctx.Idents.get(NameString);
1024   return II->getTokenID() ==  tok::identifier;
1025 }
1026 
1027 bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx,
1028                              ObjCContainerDecl *D,
1029                              ObjCMethodDecl *Method) {
1030   if (Method->isPropertyAccessor() || !Method->isInstanceMethod() ||
1031       Method->param_size() != 0)
1032     return false;
1033   // Is this method candidate to be a getter?
1034   QualType GRT = Method->getReturnType();
1035   if (GRT->isVoidType())
1036     return false;
1037 
1038   Selector GetterSelector = Method->getSelector();
1039   ObjCInstanceTypeFamily OIT_Family =
1040     Selector::getInstTypeMethodFamily(GetterSelector);
1041 
1042   if (OIT_Family != OIT_None)
1043     return false;
1044 
1045   IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0);
1046   Selector SetterSelector =
1047   SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
1048                                          PP.getSelectorTable(),
1049                                          getterName);
1050   ObjCMethodDecl *SetterMethod = D->getInstanceMethod(SetterSelector);
1051   unsigned LengthOfPrefix = 0;
1052   if (!SetterMethod) {
1053     // try a different naming convention for getter: isXxxxx
1054     StringRef getterNameString = getterName->getName();
1055     bool IsPrefix = getterNameString.startswith("is");
1056     // Note that we don't want to change an isXXX method of retainable object
1057     // type to property (readonly or otherwise).
1058     if (IsPrefix && GRT->isObjCRetainableType())
1059       return false;
1060     if (IsPrefix || getterNameString.startswith("get")) {
1061       LengthOfPrefix = (IsPrefix ? 2 : 3);
1062       const char *CGetterName = getterNameString.data() + LengthOfPrefix;
1063       // Make sure that first character after "is" or "get" prefix can
1064       // start an identifier.
1065       if (!IsValidIdentifier(Ctx, CGetterName))
1066         return false;
1067       if (CGetterName[0] && isUppercase(CGetterName[0])) {
1068         getterName = &Ctx.Idents.get(CGetterName);
1069         SetterSelector =
1070         SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
1071                                                PP.getSelectorTable(),
1072                                                getterName);
1073         SetterMethod = D->getInstanceMethod(SetterSelector);
1074       }
1075     }
1076   }
1077 
1078   if (SetterMethod) {
1079     if ((ASTMigrateActions & FrontendOptions::ObjCMT_ReadwriteProperty) == 0)
1080       return false;
1081     bool AvailabilityArgsMatch;
1082     if (SetterMethod->isDeprecated() ||
1083         !AttributesMatch(Method, SetterMethod, AvailabilityArgsMatch))
1084       return false;
1085 
1086     // Is this a valid setter, matching the target getter?
1087     QualType SRT = SetterMethod->getReturnType();
1088     if (!SRT->isVoidType())
1089       return false;
1090     const ParmVarDecl *argDecl = *SetterMethod->param_begin();
1091     QualType ArgType = argDecl->getType();
1092     if (!Ctx.hasSameUnqualifiedType(ArgType, GRT))
1093       return false;
1094     edit::Commit commit(*Editor);
1095     rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit,
1096                           LengthOfPrefix,
1097                           (ASTMigrateActions &
1098                            FrontendOptions::ObjCMT_AtomicProperty) != 0,
1099                           (ASTMigrateActions &
1100                            FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty) != 0,
1101                           AvailabilityArgsMatch);
1102     Editor->commit(commit);
1103     return true;
1104   }
1105   else if (ASTMigrateActions & FrontendOptions::ObjCMT_ReadonlyProperty) {
1106     // Try a non-void method with no argument (and no setter or property of same name
1107     // as a 'readonly' property.
1108     edit::Commit commit(*Editor);
1109     rewriteToObjCProperty(Method, nullptr /*SetterMethod*/, *NSAPIObj, commit,
1110                           LengthOfPrefix,
1111                           (ASTMigrateActions &
1112                            FrontendOptions::ObjCMT_AtomicProperty) != 0,
1113                           (ASTMigrateActions &
1114                            FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty) != 0,
1115                           /*AvailabilityArgsMatch*/false);
1116     Editor->commit(commit);
1117     return true;
1118   }
1119   return false;
1120 }
1121 
1122 void ObjCMigrateASTConsumer::migrateNsReturnsInnerPointer(ASTContext &Ctx,
1123                                                           ObjCMethodDecl *OM) {
1124   if (OM->isImplicit() ||
1125       !OM->isInstanceMethod() ||
1126       OM->hasAttr<ObjCReturnsInnerPointerAttr>())
1127     return;
1128 
1129   QualType RT = OM->getReturnType();
1130   if (!TypeIsInnerPointer(RT) ||
1131       !Ctx.Idents.get("NS_RETURNS_INNER_POINTER").hasMacroDefinition())
1132     return;
1133 
1134   edit::Commit commit(*Editor);
1135   commit.insertBefore(OM->getLocEnd(), " NS_RETURNS_INNER_POINTER");
1136   Editor->commit(commit);
1137 }
1138 
1139 void ObjCMigrateASTConsumer::migratePropertyNsReturnsInnerPointer(ASTContext &Ctx,
1140                                                                   ObjCPropertyDecl *P) {
1141   QualType T = P->getType();
1142 
1143   if (!TypeIsInnerPointer(T) ||
1144       !Ctx.Idents.get("NS_RETURNS_INNER_POINTER").hasMacroDefinition())
1145     return;
1146   edit::Commit commit(*Editor);
1147   commit.insertBefore(P->getLocEnd(), " NS_RETURNS_INNER_POINTER ");
1148   Editor->commit(commit);
1149 }
1150 
1151 void ObjCMigrateASTConsumer::migrateAllMethodInstaceType(ASTContext &Ctx,
1152                                                  ObjCContainerDecl *CDecl) {
1153   if (CDecl->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(CDecl))
1154     return;
1155 
1156   // migrate methods which can have instancetype as their result type.
1157   for (auto *Method : CDecl->methods()) {
1158     if (Method->isDeprecated())
1159       continue;
1160     migrateMethodInstanceType(Ctx, CDecl, Method);
1161   }
1162 }
1163 
1164 void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx,
1165                                                   ObjCContainerDecl *CDecl,
1166                                                   ObjCMethodDecl *OM,
1167                                                   ObjCInstanceTypeFamily OIT_Family) {
1168   if (OM->isInstanceMethod() ||
1169       OM->getReturnType() == Ctx.getObjCInstanceType() ||
1170       !OM->getReturnType()->isObjCIdType())
1171     return;
1172 
1173   // Candidate factory methods are + (id) NaMeXXX : ... which belong to a class
1174   // NSYYYNamE with matching names be at least 3 characters long.
1175   ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
1176   if (!IDecl) {
1177     if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
1178       IDecl = CatDecl->getClassInterface();
1179     else if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(CDecl))
1180       IDecl = ImpDecl->getClassInterface();
1181   }
1182   if (!IDecl)
1183     return;
1184 
1185   std::string StringClassName = IDecl->getName();
1186   StringRef LoweredClassName(StringClassName);
1187   std::string StringLoweredClassName = LoweredClassName.lower();
1188   LoweredClassName = StringLoweredClassName;
1189 
1190   IdentifierInfo *MethodIdName = OM->getSelector().getIdentifierInfoForSlot(0);
1191   // Handle method with no name at its first selector slot; e.g. + (id):(int)x.
1192   if (!MethodIdName)
1193     return;
1194 
1195   std::string MethodName = MethodIdName->getName();
1196   if (OIT_Family == OIT_Singleton || OIT_Family == OIT_ReturnsSelf) {
1197     StringRef STRefMethodName(MethodName);
1198     size_t len = 0;
1199     if (STRefMethodName.startswith("standard"))
1200       len = strlen("standard");
1201     else if (STRefMethodName.startswith("shared"))
1202       len = strlen("shared");
1203     else if (STRefMethodName.startswith("default"))
1204       len = strlen("default");
1205     else
1206       return;
1207     MethodName = STRefMethodName.substr(len);
1208   }
1209   std::string MethodNameSubStr = MethodName.substr(0, 3);
1210   StringRef MethodNamePrefix(MethodNameSubStr);
1211   std::string StringLoweredMethodNamePrefix = MethodNamePrefix.lower();
1212   MethodNamePrefix = StringLoweredMethodNamePrefix;
1213   size_t Ix = LoweredClassName.rfind(MethodNamePrefix);
1214   if (Ix == StringRef::npos)
1215     return;
1216   std::string ClassNamePostfix = LoweredClassName.substr(Ix);
1217   StringRef LoweredMethodName(MethodName);
1218   std::string StringLoweredMethodName = LoweredMethodName.lower();
1219   LoweredMethodName = StringLoweredMethodName;
1220   if (!LoweredMethodName.startswith(ClassNamePostfix))
1221     return;
1222   if (OIT_Family == OIT_ReturnsSelf)
1223     ReplaceWithClasstype(*this, OM);
1224   else
1225     ReplaceWithInstancetype(Ctx, *this, OM);
1226 }
1227 
1228 static bool IsVoidStarType(QualType Ty) {
1229   if (!Ty->isPointerType())
1230     return false;
1231 
1232   while (const TypedefType *TD = dyn_cast<TypedefType>(Ty.getTypePtr()))
1233     Ty = TD->getDecl()->getUnderlyingType();
1234 
1235   // Is the type void*?
1236   const PointerType* PT = Ty->getAs<PointerType>();
1237   if (PT->getPointeeType().getUnqualifiedType()->isVoidType())
1238     return true;
1239   return IsVoidStarType(PT->getPointeeType());
1240 }
1241 
1242 /// AuditedType - This routine audits the type AT and returns false if it is one of known
1243 /// CF object types or of the "void *" variety. It returns true if we don't care about the type
1244 /// such as a non-pointer or pointers which have no ownership issues (such as "int *").
1245 static bool AuditedType (QualType AT) {
1246   if (!AT->isAnyPointerType() && !AT->isBlockPointerType())
1247     return true;
1248   // FIXME. There isn't much we can say about CF pointer type; or is there?
1249   if (ento::coreFoundation::isCFObjectRef(AT) ||
1250       IsVoidStarType(AT) ||
1251       // If an ObjC object is type, assuming that it is not a CF function and
1252       // that it is an un-audited function.
1253       AT->isObjCObjectPointerType() || AT->isObjCBuiltinType())
1254     return false;
1255   // All other pointers are assumed audited as harmless.
1256   return true;
1257 }
1258 
1259 void ObjCMigrateASTConsumer::AnnotateImplicitBridging(ASTContext &Ctx) {
1260   if (CFFunctionIBCandidates.empty())
1261     return;
1262   if (!Ctx.Idents.get("CF_IMPLICIT_BRIDGING_ENABLED").hasMacroDefinition()) {
1263     CFFunctionIBCandidates.clear();
1264     FileId = FileID();
1265     return;
1266   }
1267   // Insert CF_IMPLICIT_BRIDGING_ENABLE/CF_IMPLICIT_BRIDGING_DISABLED
1268   const Decl *FirstFD = CFFunctionIBCandidates[0];
1269   const Decl *LastFD  =
1270     CFFunctionIBCandidates[CFFunctionIBCandidates.size()-1];
1271   const char *PragmaString = "\nCF_IMPLICIT_BRIDGING_ENABLED\n\n";
1272   edit::Commit commit(*Editor);
1273   commit.insertBefore(FirstFD->getLocStart(), PragmaString);
1274   PragmaString = "\n\nCF_IMPLICIT_BRIDGING_DISABLED\n";
1275   SourceLocation EndLoc = LastFD->getLocEnd();
1276   // get location just past end of function location.
1277   EndLoc = PP.getLocForEndOfToken(EndLoc);
1278   if (isa<FunctionDecl>(LastFD)) {
1279     // For Methods, EndLoc points to the ending semcolon. So,
1280     // not of these extra work is needed.
1281     Token Tok;
1282     // get locaiton of token that comes after end of function.
1283     bool Failed = PP.getRawToken(EndLoc, Tok, /*IgnoreWhiteSpace=*/true);
1284     if (!Failed)
1285       EndLoc = Tok.getLocation();
1286   }
1287   commit.insertAfterToken(EndLoc, PragmaString);
1288   Editor->commit(commit);
1289   FileId = FileID();
1290   CFFunctionIBCandidates.clear();
1291 }
1292 
1293 void ObjCMigrateASTConsumer::migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl) {
1294   if (Decl->isDeprecated())
1295     return;
1296 
1297   if (Decl->hasAttr<CFAuditedTransferAttr>()) {
1298     assert(CFFunctionIBCandidates.empty() &&
1299            "Cannot have audited functions/methods inside user "
1300            "provided CF_IMPLICIT_BRIDGING_ENABLE");
1301     return;
1302   }
1303 
1304   // Finction must be annotated first.
1305   if (const FunctionDecl *FuncDecl = dyn_cast<FunctionDecl>(Decl)) {
1306     CF_BRIDGING_KIND AuditKind = migrateAddFunctionAnnotation(Ctx, FuncDecl);
1307     if (AuditKind == CF_BRIDGING_ENABLE) {
1308       CFFunctionIBCandidates.push_back(Decl);
1309       if (FileId.isInvalid())
1310         FileId = PP.getSourceManager().getFileID(Decl->getLocation());
1311     }
1312     else if (AuditKind == CF_BRIDGING_MAY_INCLUDE) {
1313       if (!CFFunctionIBCandidates.empty()) {
1314         CFFunctionIBCandidates.push_back(Decl);
1315         if (FileId.isInvalid())
1316           FileId = PP.getSourceManager().getFileID(Decl->getLocation());
1317       }
1318     }
1319     else
1320       AnnotateImplicitBridging(Ctx);
1321   }
1322   else {
1323     migrateAddMethodAnnotation(Ctx, cast<ObjCMethodDecl>(Decl));
1324     AnnotateImplicitBridging(Ctx);
1325   }
1326 }
1327 
1328 void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
1329                                               const CallEffects &CE,
1330                                               const FunctionDecl *FuncDecl,
1331                                               bool ResultAnnotated) {
1332   // Annotate function.
1333   if (!ResultAnnotated) {
1334     RetEffect Ret = CE.getReturnValue();
1335     const char *AnnotationString = nullptr;
1336     if (Ret.getObjKind() == RetEffect::CF) {
1337       if (Ret.isOwned() &&
1338           Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
1339         AnnotationString = " CF_RETURNS_RETAINED";
1340       else if (Ret.notOwned() &&
1341                Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition())
1342         AnnotationString = " CF_RETURNS_NOT_RETAINED";
1343     }
1344     else if (Ret.getObjKind() == RetEffect::ObjC) {
1345       if (Ret.isOwned() &&
1346           Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition())
1347         AnnotationString = " NS_RETURNS_RETAINED";
1348     }
1349 
1350     if (AnnotationString) {
1351       edit::Commit commit(*Editor);
1352       commit.insertAfterToken(FuncDecl->getLocEnd(), AnnotationString);
1353       Editor->commit(commit);
1354     }
1355   }
1356   ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1357   unsigned i = 0;
1358   for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
1359        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
1360     const ParmVarDecl *pd = *pi;
1361     ArgEffect AE = AEArgs[i];
1362     if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
1363         Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
1364       edit::Commit commit(*Editor);
1365       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
1366       Editor->commit(commit);
1367     }
1368     else if (AE == DecRefMsg && !pd->hasAttr<NSConsumedAttr>() &&
1369              Ctx.Idents.get("NS_CONSUMED").hasMacroDefinition()) {
1370       edit::Commit commit(*Editor);
1371       commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
1372       Editor->commit(commit);
1373     }
1374   }
1375 }
1376 
1377 
1378 ObjCMigrateASTConsumer::CF_BRIDGING_KIND
1379   ObjCMigrateASTConsumer::migrateAddFunctionAnnotation(
1380                                                   ASTContext &Ctx,
1381                                                   const FunctionDecl *FuncDecl) {
1382   if (FuncDecl->hasBody())
1383     return CF_BRIDGING_NONE;
1384 
1385   CallEffects CE  = CallEffects::getEffect(FuncDecl);
1386   bool FuncIsReturnAnnotated = (FuncDecl->hasAttr<CFReturnsRetainedAttr>() ||
1387                                 FuncDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
1388                                 FuncDecl->hasAttr<NSReturnsRetainedAttr>() ||
1389                                 FuncDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
1390                                 FuncDecl->hasAttr<NSReturnsAutoreleasedAttr>());
1391 
1392   // Trivial case of when funciton is annotated and has no argument.
1393   if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0)
1394     return CF_BRIDGING_NONE;
1395 
1396   bool ReturnCFAudited = false;
1397   if (!FuncIsReturnAnnotated) {
1398     RetEffect Ret = CE.getReturnValue();
1399     if (Ret.getObjKind() == RetEffect::CF &&
1400         (Ret.isOwned() || Ret.notOwned()))
1401       ReturnCFAudited = true;
1402     else if (!AuditedType(FuncDecl->getReturnType()))
1403       return CF_BRIDGING_NONE;
1404   }
1405 
1406   // At this point result type is audited for potential inclusion.
1407   // Now, how about argument types.
1408   ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1409   unsigned i = 0;
1410   bool ArgCFAudited = false;
1411   for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
1412        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
1413     const ParmVarDecl *pd = *pi;
1414     ArgEffect AE = AEArgs[i];
1415     if (AE == DecRef /*CFConsumed annotated*/ || AE == IncRef) {
1416       if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>())
1417         ArgCFAudited = true;
1418       else if (AE == IncRef)
1419         ArgCFAudited = true;
1420     }
1421     else {
1422       QualType AT = pd->getType();
1423       if (!AuditedType(AT)) {
1424         AddCFAnnotations(Ctx, CE, FuncDecl, FuncIsReturnAnnotated);
1425         return CF_BRIDGING_NONE;
1426       }
1427     }
1428   }
1429   if (ReturnCFAudited || ArgCFAudited)
1430     return CF_BRIDGING_ENABLE;
1431 
1432   return CF_BRIDGING_MAY_INCLUDE;
1433 }
1434 
1435 void ObjCMigrateASTConsumer::migrateARCSafeAnnotation(ASTContext &Ctx,
1436                                                  ObjCContainerDecl *CDecl) {
1437   if (!isa<ObjCInterfaceDecl>(CDecl) || CDecl->isDeprecated())
1438     return;
1439 
1440   // migrate methods which can have instancetype as their result type.
1441   for (const auto *Method : CDecl->methods())
1442     migrateCFAnnotation(Ctx, Method);
1443 }
1444 
1445 void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
1446                                               const CallEffects &CE,
1447                                               const ObjCMethodDecl *MethodDecl,
1448                                               bool ResultAnnotated) {
1449   // Annotate function.
1450   if (!ResultAnnotated) {
1451     RetEffect Ret = CE.getReturnValue();
1452     const char *AnnotationString = nullptr;
1453     if (Ret.getObjKind() == RetEffect::CF) {
1454       if (Ret.isOwned() &&
1455           Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
1456         AnnotationString = " CF_RETURNS_RETAINED";
1457       else if (Ret.notOwned() &&
1458                Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition())
1459         AnnotationString = " CF_RETURNS_NOT_RETAINED";
1460     }
1461     else if (Ret.getObjKind() == RetEffect::ObjC) {
1462       ObjCMethodFamily OMF = MethodDecl->getMethodFamily();
1463       switch (OMF) {
1464         case clang::OMF_alloc:
1465         case clang::OMF_new:
1466         case clang::OMF_copy:
1467         case clang::OMF_init:
1468         case clang::OMF_mutableCopy:
1469           break;
1470 
1471         default:
1472           if (Ret.isOwned() &&
1473               Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition())
1474             AnnotationString = " NS_RETURNS_RETAINED";
1475           break;
1476       }
1477     }
1478 
1479     if (AnnotationString) {
1480       edit::Commit commit(*Editor);
1481       commit.insertBefore(MethodDecl->getLocEnd(), AnnotationString);
1482       Editor->commit(commit);
1483     }
1484   }
1485   ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1486   unsigned i = 0;
1487   for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
1488        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
1489     const ParmVarDecl *pd = *pi;
1490     ArgEffect AE = AEArgs[i];
1491     if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
1492         Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
1493       edit::Commit commit(*Editor);
1494       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
1495       Editor->commit(commit);
1496     }
1497   }
1498 }
1499 
1500 void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
1501                                             ASTContext &Ctx,
1502                                             const ObjCMethodDecl *MethodDecl) {
1503   if (MethodDecl->hasBody() || MethodDecl->isImplicit())
1504     return;
1505 
1506   CallEffects CE  = CallEffects::getEffect(MethodDecl);
1507   bool MethodIsReturnAnnotated = (MethodDecl->hasAttr<CFReturnsRetainedAttr>() ||
1508                                   MethodDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
1509                                   MethodDecl->hasAttr<NSReturnsRetainedAttr>() ||
1510                                   MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
1511                                   MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>());
1512 
1513   if (CE.getReceiver() ==  DecRefMsg &&
1514       !MethodDecl->hasAttr<NSConsumesSelfAttr>() &&
1515       MethodDecl->getMethodFamily() != OMF_init &&
1516       MethodDecl->getMethodFamily() != OMF_release &&
1517       Ctx.Idents.get("NS_CONSUMES_SELF").hasMacroDefinition()) {
1518     edit::Commit commit(*Editor);
1519     commit.insertBefore(MethodDecl->getLocEnd(), " NS_CONSUMES_SELF");
1520     Editor->commit(commit);
1521   }
1522 
1523   // Trivial case of when funciton is annotated and has no argument.
1524   if (MethodIsReturnAnnotated &&
1525       (MethodDecl->param_begin() == MethodDecl->param_end()))
1526     return;
1527 
1528   if (!MethodIsReturnAnnotated) {
1529     RetEffect Ret = CE.getReturnValue();
1530     if ((Ret.getObjKind() == RetEffect::CF ||
1531          Ret.getObjKind() == RetEffect::ObjC) &&
1532         (Ret.isOwned() || Ret.notOwned())) {
1533       AddCFAnnotations(Ctx, CE, MethodDecl, false);
1534       return;
1535     } else if (!AuditedType(MethodDecl->getReturnType()))
1536       return;
1537   }
1538 
1539   // At this point result type is either annotated or audited.
1540   // Now, how about argument types.
1541   ArrayRef<ArgEffect> AEArgs = CE.getArgs();
1542   unsigned i = 0;
1543   for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
1544        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
1545     const ParmVarDecl *pd = *pi;
1546     ArgEffect AE = AEArgs[i];
1547     if ((AE == DecRef && !pd->hasAttr<CFConsumedAttr>()) || AE == IncRef ||
1548         !AuditedType(pd->getType())) {
1549       AddCFAnnotations(Ctx, CE, MethodDecl, MethodIsReturnAnnotated);
1550       return;
1551     }
1552   }
1553   return;
1554 }
1555 
1556 namespace {
1557 class SuperInitChecker : public RecursiveASTVisitor<SuperInitChecker> {
1558 public:
1559   bool shouldVisitTemplateInstantiations() const { return false; }
1560   bool shouldWalkTypesOfTypeLocs() const { return false; }
1561 
1562   bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
1563     if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
1564       if (E->getMethodFamily() == OMF_init)
1565         return false;
1566     }
1567     return true;
1568   }
1569 };
1570 } // anonymous namespace
1571 
1572 static bool hasSuperInitCall(const ObjCMethodDecl *MD) {
1573   return !SuperInitChecker().TraverseStmt(MD->getBody());
1574 }
1575 
1576 void ObjCMigrateASTConsumer::inferDesignatedInitializers(
1577     ASTContext &Ctx,
1578     const ObjCImplementationDecl *ImplD) {
1579 
1580   const ObjCInterfaceDecl *IFace = ImplD->getClassInterface();
1581   if (!IFace || IFace->hasDesignatedInitializers())
1582     return;
1583   if (!Ctx.Idents.get("NS_DESIGNATED_INITIALIZER").hasMacroDefinition())
1584     return;
1585 
1586   for (const auto *MD : ImplD->instance_methods()) {
1587     if (MD->isDeprecated() ||
1588         MD->getMethodFamily() != OMF_init ||
1589         MD->isDesignatedInitializerForTheInterface())
1590       continue;
1591     const ObjCMethodDecl *IFaceM = IFace->getMethod(MD->getSelector(),
1592                                                     /*isInstance=*/true);
1593     if (!IFaceM)
1594       continue;
1595     if (hasSuperInitCall(MD)) {
1596       edit::Commit commit(*Editor);
1597       commit.insert(IFaceM->getLocEnd(), " NS_DESIGNATED_INITIALIZER");
1598       Editor->commit(commit);
1599     }
1600   }
1601 }
1602 
1603 namespace {
1604 
1605 class RewritesReceiver : public edit::EditsReceiver {
1606   Rewriter &Rewrite;
1607 
1608 public:
1609   RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
1610 
1611   void insert(SourceLocation loc, StringRef text) override {
1612     Rewrite.InsertText(loc, text);
1613   }
1614   void replace(CharSourceRange range, StringRef text) override {
1615     Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
1616   }
1617 };
1618 
1619 class JSONEditWriter : public edit::EditsReceiver {
1620   SourceManager &SourceMgr;
1621   llvm::raw_ostream &OS;
1622 
1623 public:
1624   JSONEditWriter(SourceManager &SM, llvm::raw_ostream &OS)
1625     : SourceMgr(SM), OS(OS) {
1626     OS << "[\n";
1627   }
1628   ~JSONEditWriter() {
1629     OS << "]\n";
1630   }
1631 
1632 private:
1633   struct EntryWriter {
1634     SourceManager &SourceMgr;
1635     llvm::raw_ostream &OS;
1636 
1637     EntryWriter(SourceManager &SM, llvm::raw_ostream &OS)
1638       : SourceMgr(SM), OS(OS) {
1639       OS << " {\n";
1640     }
1641     ~EntryWriter() {
1642       OS << " },\n";
1643     }
1644 
1645     void writeLoc(SourceLocation Loc) {
1646       FileID FID;
1647       unsigned Offset;
1648       std::tie(FID, Offset) = SourceMgr.getDecomposedLoc(Loc);
1649       assert(!FID.isInvalid());
1650       SmallString<200> Path =
1651           StringRef(SourceMgr.getFileEntryForID(FID)->getName());
1652       llvm::sys::fs::make_absolute(Path);
1653       OS << "  \"file\": \"";
1654       OS.write_escaped(Path.str()) << "\",\n";
1655       OS << "  \"offset\": " << Offset << ",\n";
1656     }
1657 
1658     void writeRemove(CharSourceRange Range) {
1659       assert(Range.isCharRange());
1660       std::pair<FileID, unsigned> Begin =
1661           SourceMgr.getDecomposedLoc(Range.getBegin());
1662       std::pair<FileID, unsigned> End =
1663           SourceMgr.getDecomposedLoc(Range.getEnd());
1664       assert(Begin.first == End.first);
1665       assert(Begin.second <= End.second);
1666       unsigned Length = End.second - Begin.second;
1667 
1668       OS << "  \"remove\": " << Length << ",\n";
1669     }
1670 
1671     void writeText(StringRef Text) {
1672       OS << "  \"text\": \"";
1673       OS.write_escaped(Text) << "\",\n";
1674     }
1675   };
1676 
1677   void insert(SourceLocation Loc, StringRef Text) override {
1678     EntryWriter Writer(SourceMgr, OS);
1679     Writer.writeLoc(Loc);
1680     Writer.writeText(Text);
1681   }
1682 
1683   void replace(CharSourceRange Range, StringRef Text) override {
1684     EntryWriter Writer(SourceMgr, OS);
1685     Writer.writeLoc(Range.getBegin());
1686     Writer.writeRemove(Range);
1687     Writer.writeText(Text);
1688   }
1689 
1690   void remove(CharSourceRange Range) override {
1691     EntryWriter Writer(SourceMgr, OS);
1692     Writer.writeLoc(Range.getBegin());
1693     Writer.writeRemove(Range);
1694   }
1695 };
1696 
1697 }
1698 
1699 void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
1700 
1701   TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
1702   if (ASTMigrateActions & FrontendOptions::ObjCMT_MigrateDecls) {
1703     for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end();
1704          D != DEnd; ++D) {
1705       FileID FID = PP.getSourceManager().getFileID((*D)->getLocation());
1706       if (!FID.isInvalid())
1707         if (!FileId.isInvalid() && FileId != FID) {
1708           if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
1709             AnnotateImplicitBridging(Ctx);
1710         }
1711 
1712       if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D))
1713         if (canModify(CDecl))
1714           migrateObjCInterfaceDecl(Ctx, CDecl);
1715       if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(*D)) {
1716         if (canModify(CatDecl))
1717           migrateObjCInterfaceDecl(Ctx, CatDecl);
1718       }
1719       else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(*D))
1720         ObjCProtocolDecls.insert(PDecl->getCanonicalDecl());
1721       else if (const ObjCImplementationDecl *ImpDecl =
1722                dyn_cast<ObjCImplementationDecl>(*D)) {
1723         if ((ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance) &&
1724             canModify(ImpDecl))
1725           migrateProtocolConformance(Ctx, ImpDecl);
1726       }
1727       else if (const EnumDecl *ED = dyn_cast<EnumDecl>(*D)) {
1728         if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros))
1729           continue;
1730         if (!canModify(ED))
1731           continue;
1732         DeclContext::decl_iterator N = D;
1733         if (++N != DEnd) {
1734           const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N);
1735           if (migrateNSEnumDecl(Ctx, ED, TD) && TD)
1736             D++;
1737         }
1738         else
1739           migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */nullptr);
1740       }
1741       else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*D)) {
1742         if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros))
1743           continue;
1744         if (!canModify(TD))
1745           continue;
1746         DeclContext::decl_iterator N = D;
1747         if (++N == DEnd)
1748           continue;
1749         if (const EnumDecl *ED = dyn_cast<EnumDecl>(*N)) {
1750           if (++N != DEnd)
1751             if (const TypedefDecl *TDF = dyn_cast<TypedefDecl>(*N)) {
1752               // prefer typedef-follows-enum to enum-follows-typedef pattern.
1753               if (migrateNSEnumDecl(Ctx, ED, TDF)) {
1754                 ++D; ++D;
1755                 CacheObjCNSIntegerTypedefed(TD);
1756                 continue;
1757               }
1758             }
1759           if (migrateNSEnumDecl(Ctx, ED, TD)) {
1760             ++D;
1761             continue;
1762           }
1763         }
1764         CacheObjCNSIntegerTypedefed(TD);
1765       }
1766       else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*D)) {
1767         if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
1768             canModify(FD))
1769           migrateCFAnnotation(Ctx, FD);
1770       }
1771 
1772       if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(*D)) {
1773         bool CanModify = canModify(CDecl);
1774         // migrate methods which can have instancetype as their result type.
1775         if ((ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype) &&
1776             CanModify)
1777           migrateAllMethodInstaceType(Ctx, CDecl);
1778         // annotate methods with CF annotations.
1779         if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
1780             CanModify)
1781           migrateARCSafeAnnotation(Ctx, CDecl);
1782       }
1783 
1784       if (const ObjCImplementationDecl *
1785             ImplD = dyn_cast<ObjCImplementationDecl>(*D)) {
1786         if ((ASTMigrateActions & FrontendOptions::ObjCMT_DesignatedInitializer) &&
1787             canModify(ImplD))
1788           inferDesignatedInitializers(Ctx, ImplD);
1789       }
1790     }
1791     if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
1792       AnnotateImplicitBridging(Ctx);
1793   }
1794 
1795  if (IsOutputFile) {
1796    std::string Error;
1797    llvm::raw_fd_ostream OS(MigrateDir.c_str(), Error, llvm::sys::fs::F_None);
1798     if (!Error.empty()) {
1799       DiagnosticsEngine &Diags = Ctx.getDiagnostics();
1800       Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
1801           << Error;
1802       return;
1803     }
1804 
1805    JSONEditWriter Writer(Ctx.getSourceManager(), OS);
1806    Editor->applyRewrites(Writer);
1807    return;
1808  }
1809 
1810   Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
1811   RewritesReceiver Rec(rewriter);
1812   Editor->applyRewrites(Rec);
1813 
1814   for (Rewriter::buffer_iterator
1815         I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) {
1816     FileID FID = I->first;
1817     RewriteBuffer &buf = I->second;
1818     const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID);
1819     assert(file);
1820     SmallString<512> newText;
1821     llvm::raw_svector_ostream vecOS(newText);
1822     buf.write(vecOS);
1823     vecOS.flush();
1824     llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy(
1825                    StringRef(newText.data(), newText.size()), file->getName());
1826     SmallString<64> filePath(file->getName());
1827     FileMgr.FixupRelativePath(filePath);
1828     Remapper.remap(filePath.str(), memBuf);
1829   }
1830 
1831   if (IsOutputFile) {
1832     Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics());
1833   } else {
1834     Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics());
1835   }
1836 }
1837 
1838 bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) {
1839   CI.getDiagnostics().setIgnoreAllWarnings(true);
1840   return true;
1841 }
1842 
1843 static std::vector<std::string> getWhiteListFilenames(StringRef DirPath) {
1844   using namespace llvm::sys::fs;
1845   using namespace llvm::sys::path;
1846 
1847   std::vector<std::string> Filenames;
1848   if (DirPath.empty() || !is_directory(DirPath))
1849     return Filenames;
1850 
1851   std::error_code EC;
1852   directory_iterator DI = directory_iterator(DirPath, EC);
1853   directory_iterator DE;
1854   for (; !EC && DI != DE; DI = DI.increment(EC)) {
1855     if (is_regular_file(DI->path()))
1856       Filenames.push_back(filename(DI->path()));
1857   }
1858 
1859   return Filenames;
1860 }
1861 
1862 std::unique_ptr<ASTConsumer>
1863 MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
1864   PPConditionalDirectiveRecord *
1865     PPRec = new PPConditionalDirectiveRecord(CI.getSourceManager());
1866   unsigned ObjCMTAction = CI.getFrontendOpts().ObjCMTAction;
1867   unsigned ObjCMTOpts = ObjCMTAction;
1868   // These are companion flags, they do not enable transformations.
1869   ObjCMTOpts &= ~(FrontendOptions::ObjCMT_AtomicProperty |
1870                   FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty);
1871   if (ObjCMTOpts == FrontendOptions::ObjCMT_None) {
1872     // If no specific option was given, enable literals+subscripting transforms
1873     // by default.
1874     ObjCMTAction |= FrontendOptions::ObjCMT_Literals |
1875                     FrontendOptions::ObjCMT_Subscripting;
1876   }
1877   CI.getPreprocessor().addPPCallbacks(PPRec);
1878   std::vector<std::string> WhiteList =
1879     getWhiteListFilenames(CI.getFrontendOpts().ObjCMTWhiteListPath);
1880   return llvm::make_unique<ObjCMigrateASTConsumer>(
1881       CI.getFrontendOpts().OutputFile, ObjCMTAction, Remapper,
1882       CI.getFileManager(), PPRec, CI.getPreprocessor(),
1883       /*isOutputFile=*/true, WhiteList);
1884 }
1885 
1886 namespace {
1887 struct EditEntry {
1888   const FileEntry *File;
1889   unsigned Offset;
1890   unsigned RemoveLen;
1891   std::string Text;
1892 
1893   EditEntry() : File(), Offset(), RemoveLen() {}
1894 };
1895 }
1896 
1897 namespace llvm {
1898 template<> struct DenseMapInfo<EditEntry> {
1899   static inline EditEntry getEmptyKey() {
1900     EditEntry Entry;
1901     Entry.Offset = unsigned(-1);
1902     return Entry;
1903   }
1904   static inline EditEntry getTombstoneKey() {
1905     EditEntry Entry;
1906     Entry.Offset = unsigned(-2);
1907     return Entry;
1908   }
1909   static unsigned getHashValue(const EditEntry& Val) {
1910     llvm::FoldingSetNodeID ID;
1911     ID.AddPointer(Val.File);
1912     ID.AddInteger(Val.Offset);
1913     ID.AddInteger(Val.RemoveLen);
1914     ID.AddString(Val.Text);
1915     return ID.ComputeHash();
1916   }
1917   static bool isEqual(const EditEntry &LHS, const EditEntry &RHS) {
1918     return LHS.File == RHS.File &&
1919         LHS.Offset == RHS.Offset &&
1920         LHS.RemoveLen == RHS.RemoveLen &&
1921         LHS.Text == RHS.Text;
1922   }
1923 };
1924 }
1925 
1926 namespace {
1927 class RemapFileParser {
1928   FileManager &FileMgr;
1929 
1930 public:
1931   RemapFileParser(FileManager &FileMgr) : FileMgr(FileMgr) { }
1932 
1933   bool parse(StringRef File, SmallVectorImpl<EditEntry> &Entries) {
1934     using namespace llvm::yaml;
1935 
1936     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
1937         llvm::MemoryBuffer::getFile(File);
1938     if (!FileBufOrErr)
1939       return true;
1940 
1941     llvm::SourceMgr SM;
1942     Stream YAMLStream(FileBufOrErr.get().release(), SM);
1943     document_iterator I = YAMLStream.begin();
1944     if (I == YAMLStream.end())
1945       return true;
1946     Node *Root = I->getRoot();
1947     if (!Root)
1948       return true;
1949 
1950     SequenceNode *SeqNode = dyn_cast<SequenceNode>(Root);
1951     if (!SeqNode)
1952       return true;
1953 
1954     for (SequenceNode::iterator
1955            AI = SeqNode->begin(), AE = SeqNode->end(); AI != AE; ++AI) {
1956       MappingNode *MapNode = dyn_cast<MappingNode>(&*AI);
1957       if (!MapNode)
1958         continue;
1959       parseEdit(MapNode, Entries);
1960     }
1961 
1962     return false;
1963   }
1964 
1965 private:
1966   void parseEdit(llvm::yaml::MappingNode *Node,
1967                  SmallVectorImpl<EditEntry> &Entries) {
1968     using namespace llvm::yaml;
1969     EditEntry Entry;
1970     bool Ignore = false;
1971 
1972     for (MappingNode::iterator
1973            KVI = Node->begin(), KVE = Node->end(); KVI != KVE; ++KVI) {
1974       ScalarNode *KeyString = dyn_cast<ScalarNode>((*KVI).getKey());
1975       if (!KeyString)
1976         continue;
1977       SmallString<10> KeyStorage;
1978       StringRef Key = KeyString->getValue(KeyStorage);
1979 
1980       ScalarNode *ValueString = dyn_cast<ScalarNode>((*KVI).getValue());
1981       if (!ValueString)
1982         continue;
1983       SmallString<64> ValueStorage;
1984       StringRef Val = ValueString->getValue(ValueStorage);
1985 
1986       if (Key == "file") {
1987         const FileEntry *FE = FileMgr.getFile(Val);
1988         if (!FE)
1989           Ignore = true;
1990         Entry.File = FE;
1991       } else if (Key == "offset") {
1992         if (Val.getAsInteger(10, Entry.Offset))
1993           Ignore = true;
1994       } else if (Key == "remove") {
1995         if (Val.getAsInteger(10, Entry.RemoveLen))
1996           Ignore = true;
1997       } else if (Key == "text") {
1998         Entry.Text = Val;
1999       }
2000     }
2001 
2002     if (!Ignore)
2003       Entries.push_back(Entry);
2004   }
2005 };
2006 }
2007 
2008 static bool reportDiag(const Twine &Err, DiagnosticsEngine &Diag) {
2009   Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
2010       << Err.str();
2011   return true;
2012 }
2013 
2014 static std::string applyEditsToTemp(const FileEntry *FE,
2015                                     ArrayRef<EditEntry> Edits,
2016                                     FileManager &FileMgr,
2017                                     DiagnosticsEngine &Diag) {
2018   using namespace llvm::sys;
2019 
2020   SourceManager SM(Diag, FileMgr);
2021   FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
2022   LangOptions LangOpts;
2023   edit::EditedSource Editor(SM, LangOpts);
2024   for (ArrayRef<EditEntry>::iterator
2025         I = Edits.begin(), E = Edits.end(); I != E; ++I) {
2026     const EditEntry &Entry = *I;
2027     assert(Entry.File == FE);
2028     SourceLocation Loc =
2029         SM.getLocForStartOfFile(FID).getLocWithOffset(Entry.Offset);
2030     CharSourceRange Range;
2031     if (Entry.RemoveLen != 0) {
2032       Range = CharSourceRange::getCharRange(Loc,
2033                                          Loc.getLocWithOffset(Entry.RemoveLen));
2034     }
2035 
2036     edit::Commit commit(Editor);
2037     if (Range.isInvalid()) {
2038       commit.insert(Loc, Entry.Text);
2039     } else if (Entry.Text.empty()) {
2040       commit.remove(Range);
2041     } else {
2042       commit.replace(Range, Entry.Text);
2043     }
2044     Editor.commit(commit);
2045   }
2046 
2047   Rewriter rewriter(SM, LangOpts);
2048   RewritesReceiver Rec(rewriter);
2049   Editor.applyRewrites(Rec);
2050 
2051   const RewriteBuffer *Buf = rewriter.getRewriteBufferFor(FID);
2052   SmallString<512> NewText;
2053   llvm::raw_svector_ostream OS(NewText);
2054   Buf->write(OS);
2055   OS.flush();
2056 
2057   SmallString<64> TempPath;
2058   int FD;
2059   if (fs::createTemporaryFile(path::filename(FE->getName()),
2060                               path::extension(FE->getName()), FD,
2061                               TempPath)) {
2062     reportDiag("Could not create file: " + TempPath.str(), Diag);
2063     return std::string();
2064   }
2065 
2066   llvm::raw_fd_ostream TmpOut(FD, /*shouldClose=*/true);
2067   TmpOut.write(NewText.data(), NewText.size());
2068   TmpOut.close();
2069 
2070   return TempPath.str();
2071 }
2072 
2073 bool arcmt::getFileRemappingsFromFileList(
2074                         std::vector<std::pair<std::string,std::string> > &remap,
2075                         ArrayRef<StringRef> remapFiles,
2076                         DiagnosticConsumer *DiagClient) {
2077   bool hasErrorOccurred = false;
2078 
2079   FileSystemOptions FSOpts;
2080   FileManager FileMgr(FSOpts);
2081   RemapFileParser Parser(FileMgr);
2082 
2083   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
2084   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
2085       new DiagnosticsEngine(DiagID, new DiagnosticOptions,
2086                             DiagClient, /*ShouldOwnClient=*/false));
2087 
2088   typedef llvm::DenseMap<const FileEntry *, std::vector<EditEntry> >
2089       FileEditEntriesTy;
2090   FileEditEntriesTy FileEditEntries;
2091 
2092   llvm::DenseSet<EditEntry> EntriesSet;
2093 
2094   for (ArrayRef<StringRef>::iterator
2095          I = remapFiles.begin(), E = remapFiles.end(); I != E; ++I) {
2096     SmallVector<EditEntry, 16> Entries;
2097     if (Parser.parse(*I, Entries))
2098       continue;
2099 
2100     for (SmallVectorImpl<EditEntry>::iterator
2101            EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) {
2102       EditEntry &Entry = *EI;
2103       if (!Entry.File)
2104         continue;
2105       std::pair<llvm::DenseSet<EditEntry>::iterator, bool>
2106         Insert = EntriesSet.insert(Entry);
2107       if (!Insert.second)
2108         continue;
2109 
2110       FileEditEntries[Entry.File].push_back(Entry);
2111     }
2112   }
2113 
2114   for (FileEditEntriesTy::iterator
2115          I = FileEditEntries.begin(), E = FileEditEntries.end(); I != E; ++I) {
2116     std::string TempFile = applyEditsToTemp(I->first, I->second,
2117                                             FileMgr, *Diags);
2118     if (TempFile.empty()) {
2119       hasErrorOccurred = true;
2120       continue;
2121     }
2122 
2123     remap.push_back(std::make_pair(I->first->getName(), TempFile));
2124   }
2125 
2126   return hasErrorOccurred;
2127 }
2128