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