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