xref: /llvm-project/clang/lib/ARCMigrate/ObjCMT.cpp (revision 0d150db214e2aa13a825b563c7238e1243d61db1)
1 //===--- ObjCMT.cpp - ObjC Migrate Tool -----------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Transforms.h"
10 #include "clang/Analysis/RetainSummaryManager.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 "llvm/ADT/SmallString.h"
31 #include "llvm/ADT/StringSet.h"
32 #include "llvm/Support/Path.h"
33 #include "llvm/Support/SourceMgr.h"
34 #include "llvm/Support/YAMLParser.h"
35 
36 using namespace clang;
37 using namespace arcmt;
38 using namespace ento;
39 using llvm::RewriteBuffer;
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,
69                         const RetainSummary *RS,
70                         const FunctionDecl *FuncDecl, bool ResultAnnotated);
71   void AddCFAnnotations(ASTContext &Ctx,
72                         const RetainSummary *RS,
73                         const ObjCMethodDecl *MethodDecl, bool ResultAnnotated);
74 
75   void AnnotateImplicitBridging(ASTContext &Ctx);
76 
77   CF_BRIDGING_KIND migrateAddFunctionAnnotation(ASTContext &Ctx,
78                                                 const FunctionDecl *FuncDecl);
79 
80   void migrateARCSafeAnnotation(ASTContext &Ctx, ObjCContainerDecl *CDecl);
81 
82   void migrateAddMethodAnnotation(ASTContext &Ctx,
83                                   const ObjCMethodDecl *MethodDecl);
84 
85   void inferDesignatedInitializers(ASTContext &Ctx,
86                                    const ObjCImplementationDecl *ImplD);
87 
88   bool InsertFoundation(ASTContext &Ctx, SourceLocation Loc);
89 
90   std::unique_ptr<RetainSummaryManager> Summaries;
91 
92 public:
93   std::string MigrateDir;
94   unsigned ASTMigrateActions;
95   FileID FileId;
96   const TypedefDecl *NSIntegerTypedefed;
97   const TypedefDecl *NSUIntegerTypedefed;
98   std::unique_ptr<NSAPI> NSAPIObj;
99   std::unique_ptr<edit::EditedSource> Editor;
100   FileRemapper &Remapper;
101   FileManager &FileMgr;
102   const PPConditionalDirectiveRecord *PPRec;
103   Preprocessor &PP;
104   bool IsOutputFile;
105   bool FoundationIncluded;
106   llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ObjCProtocolDecls;
107   llvm::SmallVector<const Decl *, 8> CFFunctionIBCandidates;
108   llvm::StringSet<> AllowListFilenames;
109 
110   RetainSummaryManager &getSummaryManager(ASTContext &Ctx) {
111     if (!Summaries)
112       Summaries.reset(new RetainSummaryManager(Ctx,
113                                                /*TrackNSCFObjects=*/true,
114                                                /*trackOSObjects=*/false));
115     return *Summaries;
116   }
117 
118   ObjCMigrateASTConsumer(StringRef migrateDir, unsigned astMigrateActions,
119                          FileRemapper &remapper, FileManager &fileMgr,
120                          const PPConditionalDirectiveRecord *PPRec,
121                          Preprocessor &PP, bool isOutputFile,
122                          ArrayRef<std::string> AllowList)
123       : MigrateDir(migrateDir), ASTMigrateActions(astMigrateActions),
124         NSIntegerTypedefed(nullptr), NSUIntegerTypedefed(nullptr),
125         Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP),
126         IsOutputFile(isOutputFile), FoundationIncluded(false) {
127     AllowListFilenames.insert(AllowList.begin(), AllowList.end());
128   }
129 
130 protected:
131   void Initialize(ASTContext &Context) override {
132     NSAPIObj.reset(new NSAPI(Context));
133     Editor.reset(new edit::EditedSource(Context.getSourceManager(),
134                                         Context.getLangOpts(),
135                                         PPRec));
136   }
137 
138   bool HandleTopLevelDecl(DeclGroupRef DG) override {
139     for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
140       migrateDecl(*I);
141     return true;
142   }
143   void HandleInterestingDecl(DeclGroupRef DG) override {
144     // Ignore decls from the PCH.
145   }
146   void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override {
147     ObjCMigrateASTConsumer::HandleTopLevelDecl(DG);
148   }
149 
150   void HandleTranslationUnit(ASTContext &Ctx) override;
151 
152   bool canModifyFile(StringRef Path) {
153     if (AllowListFilenames.empty())
154       return true;
155     return AllowListFilenames.contains(llvm::sys::path::filename(Path));
156   }
157   bool canModifyFile(OptionalFileEntryRef FE) {
158     if (!FE)
159       return false;
160     return canModifyFile(FE->getName());
161   }
162   bool canModifyFile(FileID FID) {
163     if (FID.isInvalid())
164       return false;
165     return canModifyFile(PP.getSourceManager().getFileEntryRefForID(FID));
166   }
167 
168   bool canModify(const Decl *D) {
169     if (!D)
170       return false;
171     if (const ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(D))
172       return canModify(CatImpl->getCategoryDecl());
173     if (const ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D))
174       return canModify(Impl->getClassInterface());
175     if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
176       return canModify(cast<Decl>(MD->getDeclContext()));
177 
178     FileID FID = PP.getSourceManager().getFileID(D->getLocation());
179     return canModifyFile(FID);
180   }
181 };
182 
183 } // end anonymous namespace
184 
185 ObjCMigrateAction::ObjCMigrateAction(
186     std::unique_ptr<FrontendAction> WrappedAction, StringRef migrateDir,
187     unsigned migrateAction)
188     : WrapperFrontendAction(std::move(WrappedAction)), MigrateDir(migrateDir),
189       ObjCMigAction(migrateAction), CompInst(nullptr) {
190   if (MigrateDir.empty())
191     MigrateDir = "."; // user current directory if none is given.
192 }
193 
194 std::unique_ptr<ASTConsumer>
195 ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
196   PPConditionalDirectiveRecord *
197     PPRec = new PPConditionalDirectiveRecord(CompInst->getSourceManager());
198   CI.getPreprocessor().addPPCallbacks(std::unique_ptr<PPCallbacks>(PPRec));
199   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
200   Consumers.push_back(WrapperFrontendAction::CreateASTConsumer(CI, InFile));
201   Consumers.push_back(std::make_unique<ObjCMigrateASTConsumer>(
202       MigrateDir, ObjCMigAction, Remapper, CompInst->getFileManager(), PPRec,
203       CompInst->getPreprocessor(), false, std::nullopt));
204   return std::make_unique<MultiplexConsumer>(std::move(Consumers));
205 }
206 
207 bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) {
208   Remapper.initFromDisk(MigrateDir, CI.getDiagnostics(),
209                         /*ignoreIfFilesChanged=*/true);
210   CompInst = &CI;
211   CI.getDiagnostics().setIgnoreAllWarnings(true);
212   return true;
213 }
214 
215 namespace {
216   // FIXME. This duplicates one in RewriteObjCFoundationAPI.cpp
217   bool subscriptOperatorNeedsParens(const Expr *FullExpr) {
218     const Expr* Expr = FullExpr->IgnoreImpCasts();
219     return !(isa<ArraySubscriptExpr>(Expr) || isa<CallExpr>(Expr) ||
220              isa<DeclRefExpr>(Expr) || isa<CXXNamedCastExpr>(Expr) ||
221              isa<CXXConstructExpr>(Expr) || isa<CXXThisExpr>(Expr) ||
222              isa<CXXTypeidExpr>(Expr) ||
223              isa<CXXUnresolvedConstructExpr>(Expr) ||
224              isa<ObjCMessageExpr>(Expr) || isa<ObjCPropertyRefExpr>(Expr) ||
225              isa<ObjCProtocolExpr>(Expr) || isa<MemberExpr>(Expr) ||
226              isa<ObjCIvarRefExpr>(Expr) || isa<ParenExpr>(FullExpr) ||
227              isa<ParenListExpr>(Expr) || isa<SizeOfPackExpr>(Expr));
228   }
229 
230   /// - Rewrite message expression for Objective-C setter and getters into
231   /// property-dot syntax.
232   bool rewriteToPropertyDotSyntax(const ObjCMessageExpr *Msg,
233                                   Preprocessor &PP,
234                                   const NSAPI &NS, edit::Commit &commit,
235                                   const ParentMap *PMap) {
236     if (!Msg || Msg->isImplicit() ||
237         (Msg->getReceiverKind() != ObjCMessageExpr::Instance &&
238          Msg->getReceiverKind() != ObjCMessageExpr::SuperInstance))
239       return false;
240     if (const Expr *Receiver = Msg->getInstanceReceiver())
241       if (Receiver->getType()->isObjCBuiltinType())
242         return false;
243 
244     const ObjCMethodDecl *Method = Msg->getMethodDecl();
245     if (!Method)
246       return false;
247     if (!Method->isPropertyAccessor())
248       return false;
249 
250     const ObjCPropertyDecl *Prop = Method->findPropertyDecl();
251     if (!Prop)
252       return false;
253 
254     SourceRange MsgRange = Msg->getSourceRange();
255     bool ReceiverIsSuper =
256       (Msg->getReceiverKind() == ObjCMessageExpr::SuperInstance);
257     // for 'super' receiver is nullptr.
258     const Expr *receiver = Msg->getInstanceReceiver();
259     bool NeedsParen =
260       ReceiverIsSuper ? false : subscriptOperatorNeedsParens(receiver);
261     bool IsGetter = (Msg->getNumArgs() == 0);
262     if (IsGetter) {
263       // Find space location range between receiver expression and getter method.
264       SourceLocation BegLoc =
265           ReceiverIsSuper ? Msg->getSuperLoc() : receiver->getEndLoc();
266       BegLoc = PP.getLocForEndOfToken(BegLoc);
267       SourceLocation EndLoc = Msg->getSelectorLoc(0);
268       SourceRange SpaceRange(BegLoc, EndLoc);
269       std::string PropertyDotString;
270       // rewrite getter method expression into: receiver.property or
271       // (receiver).property
272       if (NeedsParen) {
273         commit.insertBefore(receiver->getBeginLoc(), "(");
274         PropertyDotString = ").";
275       }
276       else
277         PropertyDotString = ".";
278       PropertyDotString += Prop->getName();
279       commit.replace(SpaceRange, PropertyDotString);
280 
281       // remove '[' ']'
282       commit.replace(SourceRange(MsgRange.getBegin(), MsgRange.getBegin()), "");
283       commit.replace(SourceRange(MsgRange.getEnd(), MsgRange.getEnd()), "");
284     } else {
285       if (NeedsParen)
286         commit.insertWrap("(", receiver->getSourceRange(), ")");
287       std::string PropertyDotString = ".";
288       PropertyDotString += Prop->getName();
289       PropertyDotString += " =";
290       const Expr*const* Args = Msg->getArgs();
291       const Expr *RHS = Args[0];
292       if (!RHS)
293         return false;
294       SourceLocation BegLoc =
295           ReceiverIsSuper ? Msg->getSuperLoc() : receiver->getEndLoc();
296       BegLoc = PP.getLocForEndOfToken(BegLoc);
297       SourceLocation EndLoc = RHS->getBeginLoc();
298       EndLoc = EndLoc.getLocWithOffset(-1);
299       const char *colon = PP.getSourceManager().getCharacterData(EndLoc);
300       // Add a space after '=' if there is no space between RHS and '='
301       if (colon && colon[0] == ':')
302         PropertyDotString += " ";
303       SourceRange Range(BegLoc, EndLoc);
304       commit.replace(Range, PropertyDotString);
305       // remove '[' ']'
306       commit.replace(SourceRange(MsgRange.getBegin(), MsgRange.getBegin()), "");
307       commit.replace(SourceRange(MsgRange.getEnd(), MsgRange.getEnd()), "");
308     }
309     return true;
310   }
311 
312 class ObjCMigrator : public RecursiveASTVisitor<ObjCMigrator> {
313   ObjCMigrateASTConsumer &Consumer;
314   ParentMap &PMap;
315 
316 public:
317   ObjCMigrator(ObjCMigrateASTConsumer &consumer, ParentMap &PMap)
318     : Consumer(consumer), PMap(PMap) { }
319 
320   bool shouldVisitTemplateInstantiations() const { return false; }
321   bool shouldWalkTypesOfTypeLocs() const { return false; }
322 
323   bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
324     if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Literals) {
325       edit::Commit commit(*Consumer.Editor);
326       edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit, &PMap);
327       Consumer.Editor->commit(commit);
328     }
329 
330     if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Subscripting) {
331       edit::Commit commit(*Consumer.Editor);
332       edit::rewriteToObjCSubscriptSyntax(E, *Consumer.NSAPIObj, commit);
333       Consumer.Editor->commit(commit);
334     }
335 
336     if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_PropertyDotSyntax) {
337       edit::Commit commit(*Consumer.Editor);
338       rewriteToPropertyDotSyntax(E, Consumer.PP, *Consumer.NSAPIObj,
339                                  commit, &PMap);
340       Consumer.Editor->commit(commit);
341     }
342 
343     return true;
344   }
345 
346   bool TraverseObjCMessageExpr(ObjCMessageExpr *E) {
347     // Do depth first; we want to rewrite the subexpressions first so that if
348     // we have to move expressions we will move them already rewritten.
349     for (Stmt *SubStmt : E->children())
350       if (!TraverseStmt(SubStmt))
351         return false;
352 
353     return WalkUpFromObjCMessageExpr(E);
354   }
355 };
356 
357 class BodyMigrator : public RecursiveASTVisitor<BodyMigrator> {
358   ObjCMigrateASTConsumer &Consumer;
359   std::unique_ptr<ParentMap> PMap;
360 
361 public:
362   BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { }
363 
364   bool shouldVisitTemplateInstantiations() const { return false; }
365   bool shouldWalkTypesOfTypeLocs() const { return false; }
366 
367   bool TraverseStmt(Stmt *S) {
368     PMap.reset(new ParentMap(S));
369     ObjCMigrator(Consumer, *PMap).TraverseStmt(S);
370     return true;
371   }
372 };
373 } // end anonymous namespace
374 
375 void ObjCMigrateASTConsumer::migrateDecl(Decl *D) {
376   if (!D)
377     return;
378   if (isa<ObjCMethodDecl>(D))
379     return; // Wait for the ObjC container declaration.
380 
381   BodyMigrator(*this).TraverseDecl(D);
382 }
383 
384 static void append_attr(std::string &PropertyString, const char *attr,
385                         bool &LParenAdded) {
386   if (!LParenAdded) {
387     PropertyString += "(";
388     LParenAdded = true;
389   }
390   else
391     PropertyString += ", ";
392   PropertyString += attr;
393 }
394 
395 static
396 void MigrateBlockOrFunctionPointerTypeVariable(std::string & PropertyString,
397                                                const std::string& TypeString,
398                                                const char *name) {
399   const char *argPtr = TypeString.c_str();
400   int paren = 0;
401   while (*argPtr) {
402     switch (*argPtr) {
403       case '(':
404         PropertyString += *argPtr;
405         paren++;
406         break;
407       case ')':
408         PropertyString += *argPtr;
409         paren--;
410         break;
411       case '^':
412       case '*':
413         PropertyString += (*argPtr);
414         if (paren == 1) {
415           PropertyString += name;
416           name = "";
417         }
418         break;
419       default:
420         PropertyString += *argPtr;
421         break;
422     }
423     argPtr++;
424   }
425 }
426 
427 static const char *PropertyMemoryAttribute(ASTContext &Context, QualType ArgType) {
428   Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime();
429   bool RetainableObject = ArgType->isObjCRetainableType();
430   if (RetainableObject &&
431       (propertyLifetime == Qualifiers::OCL_Strong
432        || propertyLifetime == Qualifiers::OCL_None)) {
433     if (const ObjCObjectPointerType *ObjPtrTy =
434         ArgType->getAs<ObjCObjectPointerType>()) {
435       ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
436       if (IDecl &&
437           IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying")))
438         return "copy";
439       else
440         return "strong";
441     }
442     else if (ArgType->isBlockPointerType())
443       return "copy";
444   } else if (propertyLifetime == Qualifiers::OCL_Weak)
445     // TODO. More precise determination of 'weak' attribute requires
446     // looking into setter's implementation for backing weak ivar.
447     return "weak";
448   else if (RetainableObject)
449     return ArgType->isBlockPointerType() ? "copy" : "strong";
450   return nullptr;
451 }
452 
453 static void rewriteToObjCProperty(const ObjCMethodDecl *Getter,
454                                   const ObjCMethodDecl *Setter,
455                                   const NSAPI &NS, edit::Commit &commit,
456                                   unsigned LengthOfPrefix,
457                                   bool Atomic, bool UseNsIosOnlyMacro,
458                                   bool AvailabilityArgsMatch) {
459   ASTContext &Context = NS.getASTContext();
460   bool LParenAdded = false;
461   std::string PropertyString = "@property ";
462   if (UseNsIosOnlyMacro && NS.isMacroDefined("NS_NONATOMIC_IOSONLY")) {
463     PropertyString += "(NS_NONATOMIC_IOSONLY";
464     LParenAdded = true;
465   } else if (!Atomic) {
466     PropertyString += "(nonatomic";
467     LParenAdded = true;
468   }
469 
470   std::string PropertyNameString = Getter->getNameAsString();
471   StringRef PropertyName(PropertyNameString);
472   if (LengthOfPrefix > 0) {
473     if (!LParenAdded) {
474       PropertyString += "(getter=";
475       LParenAdded = true;
476     }
477     else
478       PropertyString += ", getter=";
479     PropertyString += PropertyNameString;
480   }
481   // Property with no setter may be suggested as a 'readonly' property.
482   if (!Setter)
483     append_attr(PropertyString, "readonly", LParenAdded);
484 
485 
486   // Short circuit 'delegate' properties that contain the name "delegate" or
487   // "dataSource", or have exact name "target" to have 'assign' attribute.
488   if (PropertyName == "target" || PropertyName.contains("delegate") ||
489       PropertyName.contains("dataSource")) {
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 (!RT->getAs<TypedefType>()) {
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 = std::string(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->getBeginLoc(),
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->getBeginLoc();
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.ends_with("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.empty()) {
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       } else if (auto *ClassProperty = R.find_first<ObjCPropertyDecl>()) {
622         if ((ClassProperty->getPropertyAttributes() !=
623              Property->getPropertyAttributes()) ||
624             !Ctx.hasSameType(ClassProperty->getType(), Property->getType()))
625           return false;
626       } else
627         return false;
628     }
629 
630   // At this point, all required properties in this protocol conform to those
631   // declared in the class.
632   // Check that class implements the required methods of the protocol too.
633   bool HasAtleastOneRequiredMethod = false;
634   if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) {
635     if (PDecl->meth_begin() == PDecl->meth_end())
636       return HasAtleastOneRequiredProperty;
637     for (const auto *MD : PDecl->methods()) {
638       if (MD->isImplicit())
639         continue;
640       if (MD->getImplementationControl() == ObjCImplementationControl::Optional)
641         continue;
642       DeclContext::lookup_result R = ImpDecl->lookup(MD->getDeclName());
643       if (R.empty())
644         return false;
645       bool match = false;
646       HasAtleastOneRequiredMethod = true;
647       for (NamedDecl *ND : R)
648         if (ObjCMethodDecl *ImpMD = dyn_cast<ObjCMethodDecl>(ND))
649           if (Ctx.ObjCMethodsAreEqual(MD, ImpMD)) {
650             match = true;
651             break;
652           }
653       if (!match)
654         return false;
655     }
656   }
657   return HasAtleastOneRequiredProperty || HasAtleastOneRequiredMethod;
658 }
659 
660 static bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl,
661                     llvm::SmallVectorImpl<ObjCProtocolDecl*> &ConformingProtocols,
662                     const NSAPI &NS, edit::Commit &commit) {
663   const ObjCList<ObjCProtocolDecl> &Protocols = IDecl->getReferencedProtocols();
664   std::string ClassString;
665   SourceLocation EndLoc =
666   IDecl->getSuperClass() ? IDecl->getSuperClassLoc() : IDecl->getLocation();
667 
668   if (Protocols.empty()) {
669     ClassString = '<';
670     for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
671       ClassString += ConformingProtocols[i]->getNameAsString();
672       if (i != (e-1))
673         ClassString += ", ";
674     }
675     ClassString += "> ";
676   }
677   else {
678     ClassString = ", ";
679     for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
680       ClassString += ConformingProtocols[i]->getNameAsString();
681       if (i != (e-1))
682         ClassString += ", ";
683     }
684     ObjCInterfaceDecl::protocol_loc_iterator PL = IDecl->protocol_loc_end() - 1;
685     EndLoc = *PL;
686   }
687 
688   commit.insertAfterToken(EndLoc, ClassString);
689   return true;
690 }
691 
692 static StringRef GetUnsignedName(StringRef NSIntegerName) {
693   StringRef UnsignedName = llvm::StringSwitch<StringRef>(NSIntegerName)
694     .Case("int8_t", "uint8_t")
695     .Case("int16_t", "uint16_t")
696     .Case("int32_t", "uint32_t")
697     .Case("NSInteger", "NSUInteger")
698     .Case("int64_t", "uint64_t")
699     .Default(NSIntegerName);
700   return UnsignedName;
701 }
702 
703 static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
704                                 const TypedefDecl *TypedefDcl,
705                                 const NSAPI &NS, edit::Commit &commit,
706                                 StringRef NSIntegerName,
707                                 bool NSOptions) {
708   std::string ClassString;
709   if (NSOptions) {
710     ClassString = "typedef NS_OPTIONS(";
711     ClassString += GetUnsignedName(NSIntegerName);
712   }
713   else {
714     ClassString = "typedef NS_ENUM(";
715     ClassString += NSIntegerName;
716   }
717   ClassString += ", ";
718 
719   ClassString += TypedefDcl->getIdentifier()->getName();
720   ClassString += ')';
721   SourceRange R(EnumDcl->getBeginLoc(), EnumDcl->getBeginLoc());
722   commit.replace(R, ClassString);
723   SourceLocation EndOfEnumDclLoc = EnumDcl->getEndLoc();
724   EndOfEnumDclLoc = trans::findSemiAfterLocation(EndOfEnumDclLoc,
725                                                  NS.getASTContext(), /*IsDecl*/true);
726   if (EndOfEnumDclLoc.isValid()) {
727     SourceRange EnumDclRange(EnumDcl->getBeginLoc(), EndOfEnumDclLoc);
728     commit.insertFromRange(TypedefDcl->getBeginLoc(), EnumDclRange);
729   }
730   else
731     return false;
732 
733   SourceLocation EndTypedefDclLoc = TypedefDcl->getEndLoc();
734   EndTypedefDclLoc = trans::findSemiAfterLocation(EndTypedefDclLoc,
735                                                  NS.getASTContext(), /*IsDecl*/true);
736   if (EndTypedefDclLoc.isValid()) {
737     SourceRange TDRange(TypedefDcl->getBeginLoc(), EndTypedefDclLoc);
738     commit.remove(TDRange);
739   }
740   else
741     return false;
742 
743   EndOfEnumDclLoc =
744       trans::findLocationAfterSemi(EnumDcl->getEndLoc(), NS.getASTContext(),
745                                    /*IsDecl*/ true);
746   if (EndOfEnumDclLoc.isValid()) {
747     SourceLocation BeginOfEnumDclLoc = EnumDcl->getBeginLoc();
748     // FIXME. This assumes that enum decl; is immediately preceded by eoln.
749     // It is trying to remove the enum decl. lines entirely.
750     BeginOfEnumDclLoc = BeginOfEnumDclLoc.getLocWithOffset(-1);
751     commit.remove(SourceRange(BeginOfEnumDclLoc, EndOfEnumDclLoc));
752     return true;
753   }
754   return false;
755 }
756 
757 static void rewriteToNSMacroDecl(ASTContext &Ctx,
758                                  const EnumDecl *EnumDcl,
759                                 const TypedefDecl *TypedefDcl,
760                                 const NSAPI &NS, edit::Commit &commit,
761                                  bool IsNSIntegerType) {
762   QualType DesignatedEnumType = EnumDcl->getIntegerType();
763   assert(!DesignatedEnumType.isNull()
764          && "rewriteToNSMacroDecl - underlying enum type is null");
765 
766   PrintingPolicy Policy(Ctx.getPrintingPolicy());
767   std::string TypeString = DesignatedEnumType.getAsString(Policy);
768   std::string ClassString = IsNSIntegerType ? "NS_ENUM(" : "NS_OPTIONS(";
769   ClassString += TypeString;
770   ClassString += ", ";
771 
772   ClassString += TypedefDcl->getIdentifier()->getName();
773   ClassString += ") ";
774   SourceLocation EndLoc = EnumDcl->getBraceRange().getBegin();
775   if (EndLoc.isInvalid())
776     return;
777   CharSourceRange R =
778       CharSourceRange::getCharRange(EnumDcl->getBeginLoc(), EndLoc);
779   commit.replace(R, ClassString);
780   // This is to remove spaces between '}' and typedef name.
781   SourceLocation StartTypedefLoc = EnumDcl->getEndLoc();
782   StartTypedefLoc = StartTypedefLoc.getLocWithOffset(+1);
783   SourceLocation EndTypedefLoc = TypedefDcl->getEndLoc();
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->getEndLoc();
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->getBeginLoc()))
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->getBeginLoc()))
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->getBeginLoc(), OM->getBeginLoc());
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 = std::string(IDecl->getName());
985       ClassString += "*";
986     }
987   }
988   else {
989     R = SourceRange(OM->getBeginLoc(), OM->getBeginLoc());
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 auto *TD = T->getAs<TypedefType>())
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 = 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 (!isAsciiIdentifierStart(Name[0]))
1145     return false;
1146   std::string NameString = Name;
1147   NameString[0] = toLowercase(NameString[0]);
1148   const 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   const 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.starts_with("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.starts_with("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->getEndLoc(), " 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->getEndLoc(), " 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 = std::string(IDecl->getName());
1311   StringRef LoweredClassName(StringClassName);
1312   std::string StringLoweredClassName = LoweredClassName.lower();
1313   LoweredClassName = StringLoweredClassName;
1314 
1315   const IdentifierInfo *MethodIdName =
1316       OM->getSelector().getIdentifierInfoForSlot(0);
1317   // Handle method with no name at its first selector slot; e.g. + (id):(int)x.
1318   if (!MethodIdName)
1319     return;
1320 
1321   std::string MethodName = std::string(MethodIdName->getName());
1322   if (OIT_Family == OIT_Singleton || OIT_Family == OIT_ReturnsSelf) {
1323     StringRef STRefMethodName(MethodName);
1324     size_t len = 0;
1325     if (STRefMethodName.starts_with("standard"))
1326       len = strlen("standard");
1327     else if (STRefMethodName.starts_with("shared"))
1328       len = strlen("shared");
1329     else if (STRefMethodName.starts_with("default"))
1330       len = strlen("default");
1331     else
1332       return;
1333     MethodName = std::string(STRefMethodName.substr(len));
1334   }
1335   std::string MethodNameSubStr = MethodName.substr(0, 3);
1336   StringRef MethodNamePrefix(MethodNameSubStr);
1337   std::string StringLoweredMethodNamePrefix = MethodNamePrefix.lower();
1338   MethodNamePrefix = StringLoweredMethodNamePrefix;
1339   size_t Ix = LoweredClassName.rfind(MethodNamePrefix);
1340   if (Ix == StringRef::npos)
1341     return;
1342   std::string ClassNamePostfix = std::string(LoweredClassName.substr(Ix));
1343   StringRef LoweredMethodName(MethodName);
1344   std::string StringLoweredMethodName = LoweredMethodName.lower();
1345   LoweredMethodName = StringLoweredMethodName;
1346   if (!LoweredMethodName.starts_with(ClassNamePostfix))
1347     return;
1348   if (OIT_Family == OIT_ReturnsSelf)
1349     ReplaceWithClasstype(*this, OM);
1350   else
1351     ReplaceWithInstancetype(Ctx, *this, OM);
1352 }
1353 
1354 static bool IsVoidStarType(QualType Ty) {
1355   if (!Ty->isPointerType())
1356     return false;
1357 
1358   // Is the type void*?
1359   const PointerType* PT = Ty->castAs<PointerType>();
1360   if (PT->getPointeeType().getUnqualifiedType()->isVoidType())
1361     return true;
1362   return IsVoidStarType(PT->getPointeeType());
1363 }
1364 
1365 /// AuditedType - This routine audits the type AT and returns false if it is one of known
1366 /// CF object types or of the "void *" variety. It returns true if we don't care about the type
1367 /// such as a non-pointer or pointers which have no ownership issues (such as "int *").
1368 static bool AuditedType (QualType AT) {
1369   if (!AT->isAnyPointerType() && !AT->isBlockPointerType())
1370     return true;
1371   // FIXME. There isn't much we can say about CF pointer type; or is there?
1372   if (ento::coreFoundation::isCFObjectRef(AT) ||
1373       IsVoidStarType(AT) ||
1374       // If an ObjC object is type, assuming that it is not a CF function and
1375       // that it is an un-audited function.
1376       AT->isObjCObjectPointerType() || AT->isObjCBuiltinType())
1377     return false;
1378   // All other pointers are assumed audited as harmless.
1379   return true;
1380 }
1381 
1382 void ObjCMigrateASTConsumer::AnnotateImplicitBridging(ASTContext &Ctx) {
1383   if (CFFunctionIBCandidates.empty())
1384     return;
1385   if (!NSAPIObj->isMacroDefined("CF_IMPLICIT_BRIDGING_ENABLED")) {
1386     CFFunctionIBCandidates.clear();
1387     FileId = FileID();
1388     return;
1389   }
1390   // Insert CF_IMPLICIT_BRIDGING_ENABLE/CF_IMPLICIT_BRIDGING_DISABLED
1391   const Decl *FirstFD = CFFunctionIBCandidates[0];
1392   const Decl *LastFD  =
1393     CFFunctionIBCandidates[CFFunctionIBCandidates.size()-1];
1394   const char *PragmaString = "\nCF_IMPLICIT_BRIDGING_ENABLED\n\n";
1395   edit::Commit commit(*Editor);
1396   commit.insertBefore(FirstFD->getBeginLoc(), PragmaString);
1397   PragmaString = "\n\nCF_IMPLICIT_BRIDGING_DISABLED\n";
1398   SourceLocation EndLoc = LastFD->getEndLoc();
1399   // get location just past end of function location.
1400   EndLoc = PP.getLocForEndOfToken(EndLoc);
1401   if (isa<FunctionDecl>(LastFD)) {
1402     // For Methods, EndLoc points to the ending semcolon. So,
1403     // not of these extra work is needed.
1404     Token Tok;
1405     // get locaiton of token that comes after end of function.
1406     bool Failed = PP.getRawToken(EndLoc, Tok, /*IgnoreWhiteSpace=*/true);
1407     if (!Failed)
1408       EndLoc = Tok.getLocation();
1409   }
1410   commit.insertAfterToken(EndLoc, PragmaString);
1411   Editor->commit(commit);
1412   FileId = FileID();
1413   CFFunctionIBCandidates.clear();
1414 }
1415 
1416 void ObjCMigrateASTConsumer::migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl) {
1417   if (Decl->isDeprecated())
1418     return;
1419 
1420   if (Decl->hasAttr<CFAuditedTransferAttr>()) {
1421     assert(CFFunctionIBCandidates.empty() &&
1422            "Cannot have audited functions/methods inside user "
1423            "provided CF_IMPLICIT_BRIDGING_ENABLE");
1424     return;
1425   }
1426 
1427   // Finction must be annotated first.
1428   if (const FunctionDecl *FuncDecl = dyn_cast<FunctionDecl>(Decl)) {
1429     CF_BRIDGING_KIND AuditKind = migrateAddFunctionAnnotation(Ctx, FuncDecl);
1430     if (AuditKind == CF_BRIDGING_ENABLE) {
1431       CFFunctionIBCandidates.push_back(Decl);
1432       if (FileId.isInvalid())
1433         FileId = PP.getSourceManager().getFileID(Decl->getLocation());
1434     }
1435     else if (AuditKind == CF_BRIDGING_MAY_INCLUDE) {
1436       if (!CFFunctionIBCandidates.empty()) {
1437         CFFunctionIBCandidates.push_back(Decl);
1438         if (FileId.isInvalid())
1439           FileId = PP.getSourceManager().getFileID(Decl->getLocation());
1440       }
1441     }
1442     else
1443       AnnotateImplicitBridging(Ctx);
1444   }
1445   else {
1446     migrateAddMethodAnnotation(Ctx, cast<ObjCMethodDecl>(Decl));
1447     AnnotateImplicitBridging(Ctx);
1448   }
1449 }
1450 
1451 void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
1452                                               const RetainSummary *RS,
1453                                               const FunctionDecl *FuncDecl,
1454                                               bool ResultAnnotated) {
1455   // Annotate function.
1456   if (!ResultAnnotated) {
1457     RetEffect Ret = RS->getRetEffect();
1458     const char *AnnotationString = nullptr;
1459     if (Ret.getObjKind() == ObjKind::CF) {
1460       if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
1461         AnnotationString = " CF_RETURNS_RETAINED";
1462       else if (Ret.notOwned() &&
1463                NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED"))
1464         AnnotationString = " CF_RETURNS_NOT_RETAINED";
1465     }
1466     else if (Ret.getObjKind() == ObjKind::ObjC) {
1467       if (Ret.isOwned() && NSAPIObj->isMacroDefined("NS_RETURNS_RETAINED"))
1468         AnnotationString = " NS_RETURNS_RETAINED";
1469     }
1470 
1471     if (AnnotationString) {
1472       edit::Commit commit(*Editor);
1473       commit.insertAfterToken(FuncDecl->getEndLoc(), AnnotationString);
1474       Editor->commit(commit);
1475     }
1476   }
1477   unsigned i = 0;
1478   for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
1479        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
1480     const ParmVarDecl *pd = *pi;
1481     ArgEffect AE = RS->getArg(i);
1482     if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::CF &&
1483         !pd->hasAttr<CFConsumedAttr>() &&
1484         NSAPIObj->isMacroDefined("CF_CONSUMED")) {
1485       edit::Commit commit(*Editor);
1486       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
1487       Editor->commit(commit);
1488     } else if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::ObjC &&
1489                !pd->hasAttr<NSConsumedAttr>() &&
1490                NSAPIObj->isMacroDefined("NS_CONSUMED")) {
1491       edit::Commit commit(*Editor);
1492       commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
1493       Editor->commit(commit);
1494     }
1495   }
1496 }
1497 
1498 ObjCMigrateASTConsumer::CF_BRIDGING_KIND
1499   ObjCMigrateASTConsumer::migrateAddFunctionAnnotation(
1500                                                   ASTContext &Ctx,
1501                                                   const FunctionDecl *FuncDecl) {
1502   if (FuncDecl->hasBody())
1503     return CF_BRIDGING_NONE;
1504 
1505   const RetainSummary *RS =
1506       getSummaryManager(Ctx).getSummary(AnyCall(FuncDecl));
1507   bool FuncIsReturnAnnotated = (FuncDecl->hasAttr<CFReturnsRetainedAttr>() ||
1508                                 FuncDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
1509                                 FuncDecl->hasAttr<NSReturnsRetainedAttr>() ||
1510                                 FuncDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
1511                                 FuncDecl->hasAttr<NSReturnsAutoreleasedAttr>());
1512 
1513   // Trivial case of when function is annotated and has no argument.
1514   if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0)
1515     return CF_BRIDGING_NONE;
1516 
1517   bool ReturnCFAudited = false;
1518   if (!FuncIsReturnAnnotated) {
1519     RetEffect Ret = RS->getRetEffect();
1520     if (Ret.getObjKind() == ObjKind::CF &&
1521         (Ret.isOwned() || Ret.notOwned()))
1522       ReturnCFAudited = true;
1523     else if (!AuditedType(FuncDecl->getReturnType()))
1524       return CF_BRIDGING_NONE;
1525   }
1526 
1527   // At this point result type is audited for potential inclusion.
1528   unsigned i = 0;
1529   bool ArgCFAudited = false;
1530   for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
1531        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
1532     const ParmVarDecl *pd = *pi;
1533     ArgEffect AE = RS->getArg(i);
1534     if ((AE.getKind() == DecRef /*CFConsumed annotated*/ ||
1535          AE.getKind() == IncRef) && AE.getObjKind() == ObjKind::CF) {
1536       if (AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>())
1537         ArgCFAudited = true;
1538       else if (AE.getKind() == IncRef)
1539         ArgCFAudited = true;
1540     } else {
1541       QualType AT = pd->getType();
1542       if (!AuditedType(AT)) {
1543         AddCFAnnotations(Ctx, RS, FuncDecl, FuncIsReturnAnnotated);
1544         return CF_BRIDGING_NONE;
1545       }
1546     }
1547   }
1548   if (ReturnCFAudited || ArgCFAudited)
1549     return CF_BRIDGING_ENABLE;
1550 
1551   return CF_BRIDGING_MAY_INCLUDE;
1552 }
1553 
1554 void ObjCMigrateASTConsumer::migrateARCSafeAnnotation(ASTContext &Ctx,
1555                                                  ObjCContainerDecl *CDecl) {
1556   if (!isa<ObjCInterfaceDecl>(CDecl) || CDecl->isDeprecated())
1557     return;
1558 
1559   // migrate methods which can have instancetype as their result type.
1560   for (const auto *Method : CDecl->methods())
1561     migrateCFAnnotation(Ctx, Method);
1562 }
1563 
1564 void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
1565                                               const RetainSummary *RS,
1566                                               const ObjCMethodDecl *MethodDecl,
1567                                               bool ResultAnnotated) {
1568   // Annotate function.
1569   if (!ResultAnnotated) {
1570     RetEffect Ret = RS->getRetEffect();
1571     const char *AnnotationString = nullptr;
1572     if (Ret.getObjKind() == ObjKind::CF) {
1573       if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
1574         AnnotationString = " CF_RETURNS_RETAINED";
1575       else if (Ret.notOwned() &&
1576                NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED"))
1577         AnnotationString = " CF_RETURNS_NOT_RETAINED";
1578     }
1579     else if (Ret.getObjKind() == ObjKind::ObjC) {
1580       ObjCMethodFamily OMF = MethodDecl->getMethodFamily();
1581       switch (OMF) {
1582         case clang::OMF_alloc:
1583         case clang::OMF_new:
1584         case clang::OMF_copy:
1585         case clang::OMF_init:
1586         case clang::OMF_mutableCopy:
1587           break;
1588 
1589         default:
1590           if (Ret.isOwned() && NSAPIObj->isMacroDefined("NS_RETURNS_RETAINED"))
1591             AnnotationString = " NS_RETURNS_RETAINED";
1592           break;
1593       }
1594     }
1595 
1596     if (AnnotationString) {
1597       edit::Commit commit(*Editor);
1598       commit.insertBefore(MethodDecl->getEndLoc(), AnnotationString);
1599       Editor->commit(commit);
1600     }
1601   }
1602   unsigned i = 0;
1603   for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
1604        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
1605     const ParmVarDecl *pd = *pi;
1606     ArgEffect AE = RS->getArg(i);
1607     if (AE.getKind() == DecRef
1608         && AE.getObjKind() == ObjKind::CF
1609         && !pd->hasAttr<CFConsumedAttr>() &&
1610         NSAPIObj->isMacroDefined("CF_CONSUMED")) {
1611       edit::Commit commit(*Editor);
1612       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
1613       Editor->commit(commit);
1614     }
1615   }
1616 }
1617 
1618 void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
1619                                             ASTContext &Ctx,
1620                                             const ObjCMethodDecl *MethodDecl) {
1621   if (MethodDecl->hasBody() || MethodDecl->isImplicit())
1622     return;
1623 
1624   const RetainSummary *RS =
1625       getSummaryManager(Ctx).getSummary(AnyCall(MethodDecl));
1626 
1627   bool MethodIsReturnAnnotated =
1628       (MethodDecl->hasAttr<CFReturnsRetainedAttr>() ||
1629        MethodDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
1630        MethodDecl->hasAttr<NSReturnsRetainedAttr>() ||
1631        MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
1632        MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>());
1633 
1634   if (RS->getReceiverEffect().getKind() == DecRef &&
1635       !MethodDecl->hasAttr<NSConsumesSelfAttr>() &&
1636       MethodDecl->getMethodFamily() != OMF_init &&
1637       MethodDecl->getMethodFamily() != OMF_release &&
1638       NSAPIObj->isMacroDefined("NS_CONSUMES_SELF")) {
1639     edit::Commit commit(*Editor);
1640     commit.insertBefore(MethodDecl->getEndLoc(), " NS_CONSUMES_SELF");
1641     Editor->commit(commit);
1642   }
1643 
1644   // Trivial case of when function is annotated and has no argument.
1645   if (MethodIsReturnAnnotated &&
1646       (MethodDecl->param_begin() == MethodDecl->param_end()))
1647     return;
1648 
1649   if (!MethodIsReturnAnnotated) {
1650     RetEffect Ret = RS->getRetEffect();
1651     if ((Ret.getObjKind() == ObjKind::CF ||
1652          Ret.getObjKind() == ObjKind::ObjC) &&
1653         (Ret.isOwned() || Ret.notOwned())) {
1654       AddCFAnnotations(Ctx, RS, MethodDecl, false);
1655       return;
1656     } else if (!AuditedType(MethodDecl->getReturnType()))
1657       return;
1658   }
1659 
1660   // At this point result type is either annotated or audited.
1661   unsigned i = 0;
1662   for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
1663        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
1664     const ParmVarDecl *pd = *pi;
1665     ArgEffect AE = RS->getArg(i);
1666     if ((AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>()) ||
1667         AE.getKind() == IncRef || !AuditedType(pd->getType())) {
1668       AddCFAnnotations(Ctx, RS, MethodDecl, MethodIsReturnAnnotated);
1669       return;
1670     }
1671   }
1672 }
1673 
1674 namespace {
1675 class SuperInitChecker : public RecursiveASTVisitor<SuperInitChecker> {
1676 public:
1677   bool shouldVisitTemplateInstantiations() const { return false; }
1678   bool shouldWalkTypesOfTypeLocs() const { return false; }
1679 
1680   bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
1681     if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
1682       if (E->getMethodFamily() == OMF_init)
1683         return false;
1684     }
1685     return true;
1686   }
1687 };
1688 } // end anonymous namespace
1689 
1690 static bool hasSuperInitCall(const ObjCMethodDecl *MD) {
1691   return !SuperInitChecker().TraverseStmt(MD->getBody());
1692 }
1693 
1694 void ObjCMigrateASTConsumer::inferDesignatedInitializers(
1695     ASTContext &Ctx,
1696     const ObjCImplementationDecl *ImplD) {
1697 
1698   const ObjCInterfaceDecl *IFace = ImplD->getClassInterface();
1699   if (!IFace || IFace->hasDesignatedInitializers())
1700     return;
1701   if (!NSAPIObj->isMacroDefined("NS_DESIGNATED_INITIALIZER"))
1702     return;
1703 
1704   for (const auto *MD : ImplD->instance_methods()) {
1705     if (MD->isDeprecated() ||
1706         MD->getMethodFamily() != OMF_init ||
1707         MD->isDesignatedInitializerForTheInterface())
1708       continue;
1709     const ObjCMethodDecl *IFaceM = IFace->getMethod(MD->getSelector(),
1710                                                     /*isInstance=*/true);
1711     if (!IFaceM)
1712       continue;
1713     if (hasSuperInitCall(MD)) {
1714       edit::Commit commit(*Editor);
1715       commit.insert(IFaceM->getEndLoc(), " NS_DESIGNATED_INITIALIZER");
1716       Editor->commit(commit);
1717     }
1718   }
1719 }
1720 
1721 bool ObjCMigrateASTConsumer::InsertFoundation(ASTContext &Ctx,
1722                                               SourceLocation  Loc) {
1723   if (FoundationIncluded)
1724     return true;
1725   if (Loc.isInvalid())
1726     return false;
1727   auto *nsEnumId = &Ctx.Idents.get("NS_ENUM");
1728   if (PP.getMacroDefinitionAtLoc(nsEnumId, Loc)) {
1729     FoundationIncluded = true;
1730     return true;
1731   }
1732   edit::Commit commit(*Editor);
1733   if (Ctx.getLangOpts().Modules)
1734     commit.insert(Loc, "#ifndef NS_ENUM\n@import Foundation;\n#endif\n");
1735   else
1736     commit.insert(Loc, "#ifndef NS_ENUM\n#import <Foundation/Foundation.h>\n#endif\n");
1737   Editor->commit(commit);
1738   FoundationIncluded = true;
1739   return true;
1740 }
1741 
1742 namespace {
1743 
1744 class RewritesReceiver : public edit::EditsReceiver {
1745   Rewriter &Rewrite;
1746 
1747 public:
1748   RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
1749 
1750   void insert(SourceLocation loc, StringRef text) override {
1751     Rewrite.InsertText(loc, text);
1752   }
1753   void replace(CharSourceRange range, StringRef text) override {
1754     Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
1755   }
1756 };
1757 
1758 class JSONEditWriter : public edit::EditsReceiver {
1759   SourceManager &SourceMgr;
1760   llvm::raw_ostream &OS;
1761 
1762 public:
1763   JSONEditWriter(SourceManager &SM, llvm::raw_ostream &OS)
1764     : SourceMgr(SM), OS(OS) {
1765     OS << "[\n";
1766   }
1767   ~JSONEditWriter() override { OS << "]\n"; }
1768 
1769 private:
1770   struct EntryWriter {
1771     SourceManager &SourceMgr;
1772     llvm::raw_ostream &OS;
1773 
1774     EntryWriter(SourceManager &SM, llvm::raw_ostream &OS)
1775       : SourceMgr(SM), OS(OS) {
1776       OS << " {\n";
1777     }
1778     ~EntryWriter() {
1779       OS << " },\n";
1780     }
1781 
1782     void writeLoc(SourceLocation Loc) {
1783       FileID FID;
1784       unsigned Offset;
1785       std::tie(FID, Offset) = SourceMgr.getDecomposedLoc(Loc);
1786       assert(FID.isValid());
1787       SmallString<200> Path =
1788           StringRef(SourceMgr.getFileEntryRefForID(FID)->getName());
1789       llvm::sys::fs::make_absolute(Path);
1790       OS << "  \"file\": \"";
1791       OS.write_escaped(Path.str()) << "\",\n";
1792       OS << "  \"offset\": " << Offset << ",\n";
1793     }
1794 
1795     void writeRemove(CharSourceRange Range) {
1796       assert(Range.isCharRange());
1797       std::pair<FileID, unsigned> Begin =
1798           SourceMgr.getDecomposedLoc(Range.getBegin());
1799       std::pair<FileID, unsigned> End =
1800           SourceMgr.getDecomposedLoc(Range.getEnd());
1801       assert(Begin.first == End.first);
1802       assert(Begin.second <= End.second);
1803       unsigned Length = End.second - Begin.second;
1804 
1805       OS << "  \"remove\": " << Length << ",\n";
1806     }
1807 
1808     void writeText(StringRef Text) {
1809       OS << "  \"text\": \"";
1810       OS.write_escaped(Text) << "\",\n";
1811     }
1812   };
1813 
1814   void insert(SourceLocation Loc, StringRef Text) override {
1815     EntryWriter Writer(SourceMgr, OS);
1816     Writer.writeLoc(Loc);
1817     Writer.writeText(Text);
1818   }
1819 
1820   void replace(CharSourceRange Range, StringRef Text) override {
1821     EntryWriter Writer(SourceMgr, OS);
1822     Writer.writeLoc(Range.getBegin());
1823     Writer.writeRemove(Range);
1824     Writer.writeText(Text);
1825   }
1826 
1827   void remove(CharSourceRange Range) override {
1828     EntryWriter Writer(SourceMgr, OS);
1829     Writer.writeLoc(Range.getBegin());
1830     Writer.writeRemove(Range);
1831   }
1832 };
1833 
1834 } // end anonymous namespace
1835 
1836 void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
1837 
1838   TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
1839   if (ASTMigrateActions & FrontendOptions::ObjCMT_MigrateDecls) {
1840     for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end();
1841          D != DEnd; ++D) {
1842       FileID FID = PP.getSourceManager().getFileID((*D)->getLocation());
1843       if (FID.isValid())
1844         if (FileId.isValid() && FileId != FID) {
1845           if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
1846             AnnotateImplicitBridging(Ctx);
1847         }
1848 
1849       if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D))
1850         if (canModify(CDecl))
1851           migrateObjCContainerDecl(Ctx, CDecl);
1852       if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(*D)) {
1853         if (canModify(CatDecl))
1854           migrateObjCContainerDecl(Ctx, CatDecl);
1855       }
1856       else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(*D)) {
1857         ObjCProtocolDecls.insert(PDecl->getCanonicalDecl());
1858         if (canModify(PDecl))
1859           migrateObjCContainerDecl(Ctx, PDecl);
1860       }
1861       else if (const ObjCImplementationDecl *ImpDecl =
1862                dyn_cast<ObjCImplementationDecl>(*D)) {
1863         if ((ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance) &&
1864             canModify(ImpDecl))
1865           migrateProtocolConformance(Ctx, ImpDecl);
1866       }
1867       else if (const EnumDecl *ED = dyn_cast<EnumDecl>(*D)) {
1868         if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros))
1869           continue;
1870         if (!canModify(ED))
1871           continue;
1872         DeclContext::decl_iterator N = D;
1873         if (++N != DEnd) {
1874           const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N);
1875           if (migrateNSEnumDecl(Ctx, ED, TD) && TD)
1876             D++;
1877         }
1878         else
1879           migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */nullptr);
1880       }
1881       else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*D)) {
1882         if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros))
1883           continue;
1884         if (!canModify(TD))
1885           continue;
1886         DeclContext::decl_iterator N = D;
1887         if (++N == DEnd)
1888           continue;
1889         if (const EnumDecl *ED = dyn_cast<EnumDecl>(*N)) {
1890           if (canModify(ED)) {
1891             if (++N != DEnd)
1892               if (const TypedefDecl *TDF = dyn_cast<TypedefDecl>(*N)) {
1893                 // prefer typedef-follows-enum to enum-follows-typedef pattern.
1894                 if (migrateNSEnumDecl(Ctx, ED, TDF)) {
1895                   ++D; ++D;
1896                   CacheObjCNSIntegerTypedefed(TD);
1897                   continue;
1898                 }
1899               }
1900             if (migrateNSEnumDecl(Ctx, ED, TD)) {
1901               ++D;
1902               continue;
1903             }
1904           }
1905         }
1906         CacheObjCNSIntegerTypedefed(TD);
1907       }
1908       else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*D)) {
1909         if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
1910             canModify(FD))
1911           migrateCFAnnotation(Ctx, FD);
1912       }
1913 
1914       if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(*D)) {
1915         bool CanModify = canModify(CDecl);
1916         // migrate methods which can have instancetype as their result type.
1917         if ((ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype) &&
1918             CanModify)
1919           migrateAllMethodInstaceType(Ctx, CDecl);
1920         // annotate methods with CF annotations.
1921         if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
1922             CanModify)
1923           migrateARCSafeAnnotation(Ctx, CDecl);
1924       }
1925 
1926       if (const ObjCImplementationDecl *
1927             ImplD = dyn_cast<ObjCImplementationDecl>(*D)) {
1928         if ((ASTMigrateActions & FrontendOptions::ObjCMT_DesignatedInitializer) &&
1929             canModify(ImplD))
1930           inferDesignatedInitializers(Ctx, ImplD);
1931       }
1932     }
1933     if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
1934       AnnotateImplicitBridging(Ctx);
1935   }
1936 
1937  if (IsOutputFile) {
1938    std::error_code EC;
1939    llvm::raw_fd_ostream OS(MigrateDir, EC, llvm::sys::fs::OF_None);
1940    if (EC) {
1941       DiagnosticsEngine &Diags = Ctx.getDiagnostics();
1942       Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
1943           << EC.message();
1944       return;
1945     }
1946 
1947    JSONEditWriter Writer(Ctx.getSourceManager(), OS);
1948    Editor->applyRewrites(Writer);
1949    return;
1950  }
1951 
1952   Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
1953   RewritesReceiver Rec(rewriter);
1954   Editor->applyRewrites(Rec);
1955 
1956   for (Rewriter::buffer_iterator
1957         I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) {
1958     FileID FID = I->first;
1959     RewriteBuffer &buf = I->second;
1960     OptionalFileEntryRef file =
1961         Ctx.getSourceManager().getFileEntryRefForID(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(newText.str(), file->getName()));
1968     SmallString<64> filePath(file->getName());
1969     FileMgr.FixupRelativePath(filePath);
1970     Remapper.remap(filePath.str(), std::move(memBuf));
1971   }
1972 
1973   if (IsOutputFile) {
1974     Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics());
1975   } else {
1976     Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics());
1977   }
1978 }
1979 
1980 bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) {
1981   CI.getDiagnostics().setIgnoreAllWarnings(true);
1982   return true;
1983 }
1984 
1985 static std::vector<std::string> getAllowListFilenames(StringRef DirPath) {
1986   using namespace llvm::sys::fs;
1987   using namespace llvm::sys::path;
1988 
1989   std::vector<std::string> Filenames;
1990   if (DirPath.empty() || !is_directory(DirPath))
1991     return Filenames;
1992 
1993   std::error_code EC;
1994   directory_iterator DI = directory_iterator(DirPath, EC);
1995   directory_iterator DE;
1996   for (; !EC && DI != DE; DI = DI.increment(EC)) {
1997     if (is_regular_file(DI->path()))
1998       Filenames.push_back(std::string(filename(DI->path())));
1999   }
2000 
2001   return Filenames;
2002 }
2003 
2004 std::unique_ptr<ASTConsumer>
2005 MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
2006   PPConditionalDirectiveRecord *
2007     PPRec = new PPConditionalDirectiveRecord(CI.getSourceManager());
2008   unsigned ObjCMTAction = CI.getFrontendOpts().ObjCMTAction;
2009   unsigned ObjCMTOpts = ObjCMTAction;
2010   // These are companion flags, they do not enable transformations.
2011   ObjCMTOpts &= ~(FrontendOptions::ObjCMT_AtomicProperty |
2012                   FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty);
2013   if (ObjCMTOpts == FrontendOptions::ObjCMT_None) {
2014     // If no specific option was given, enable literals+subscripting transforms
2015     // by default.
2016     ObjCMTAction |=
2017         FrontendOptions::ObjCMT_Literals | FrontendOptions::ObjCMT_Subscripting;
2018   }
2019   CI.getPreprocessor().addPPCallbacks(std::unique_ptr<PPCallbacks>(PPRec));
2020   std::vector<std::string> AllowList =
2021       getAllowListFilenames(CI.getFrontendOpts().ObjCMTAllowListPath);
2022   return std::make_unique<ObjCMigrateASTConsumer>(
2023       CI.getFrontendOpts().OutputFile, ObjCMTAction, Remapper,
2024       CI.getFileManager(), PPRec, CI.getPreprocessor(),
2025       /*isOutputFile=*/true, AllowList);
2026 }
2027 
2028 namespace {
2029 struct EditEntry {
2030   OptionalFileEntryRef File;
2031   unsigned Offset = 0;
2032   unsigned RemoveLen = 0;
2033   std::string Text;
2034 };
2035 } // end anonymous namespace
2036 
2037 namespace llvm {
2038 template<> struct DenseMapInfo<EditEntry> {
2039   static inline EditEntry getEmptyKey() {
2040     EditEntry Entry;
2041     Entry.Offset = unsigned(-1);
2042     return Entry;
2043   }
2044   static inline EditEntry getTombstoneKey() {
2045     EditEntry Entry;
2046     Entry.Offset = unsigned(-2);
2047     return Entry;
2048   }
2049   static unsigned getHashValue(const EditEntry& Val) {
2050     return (unsigned)llvm::hash_combine(Val.File, Val.Offset, Val.RemoveLen,
2051                                         Val.Text);
2052   }
2053   static bool isEqual(const EditEntry &LHS, const EditEntry &RHS) {
2054     return LHS.File == RHS.File &&
2055         LHS.Offset == RHS.Offset &&
2056         LHS.RemoveLen == RHS.RemoveLen &&
2057         LHS.Text == RHS.Text;
2058   }
2059 };
2060 } // end namespace llvm
2061 
2062 namespace {
2063 class RemapFileParser {
2064   FileManager &FileMgr;
2065 
2066 public:
2067   RemapFileParser(FileManager &FileMgr) : FileMgr(FileMgr) { }
2068 
2069   bool parse(StringRef File, SmallVectorImpl<EditEntry> &Entries) {
2070     using namespace llvm::yaml;
2071 
2072     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
2073         llvm::MemoryBuffer::getFile(File);
2074     if (!FileBufOrErr)
2075       return true;
2076 
2077     llvm::SourceMgr SM;
2078     Stream YAMLStream(FileBufOrErr.get()->getMemBufferRef(), SM);
2079     document_iterator I = YAMLStream.begin();
2080     if (I == YAMLStream.end())
2081       return true;
2082     Node *Root = I->getRoot();
2083     if (!Root)
2084       return true;
2085 
2086     SequenceNode *SeqNode = dyn_cast<SequenceNode>(Root);
2087     if (!SeqNode)
2088       return true;
2089 
2090     for (SequenceNode::iterator
2091            AI = SeqNode->begin(), AE = SeqNode->end(); AI != AE; ++AI) {
2092       MappingNode *MapNode = dyn_cast<MappingNode>(&*AI);
2093       if (!MapNode)
2094         continue;
2095       parseEdit(MapNode, Entries);
2096     }
2097 
2098     return false;
2099   }
2100 
2101 private:
2102   void parseEdit(llvm::yaml::MappingNode *Node,
2103                  SmallVectorImpl<EditEntry> &Entries) {
2104     using namespace llvm::yaml;
2105     EditEntry Entry;
2106     bool Ignore = false;
2107 
2108     for (MappingNode::iterator
2109            KVI = Node->begin(), KVE = Node->end(); KVI != KVE; ++KVI) {
2110       ScalarNode *KeyString = dyn_cast<ScalarNode>((*KVI).getKey());
2111       if (!KeyString)
2112         continue;
2113       SmallString<10> KeyStorage;
2114       StringRef Key = KeyString->getValue(KeyStorage);
2115 
2116       ScalarNode *ValueString = dyn_cast<ScalarNode>((*KVI).getValue());
2117       if (!ValueString)
2118         continue;
2119       SmallString<64> ValueStorage;
2120       StringRef Val = ValueString->getValue(ValueStorage);
2121 
2122       if (Key == "file") {
2123         if (auto File = FileMgr.getOptionalFileRef(Val))
2124           Entry.File = File;
2125         else
2126           Ignore = true;
2127       } else if (Key == "offset") {
2128         if (Val.getAsInteger(10, Entry.Offset))
2129           Ignore = true;
2130       } else if (Key == "remove") {
2131         if (Val.getAsInteger(10, Entry.RemoveLen))
2132           Ignore = true;
2133       } else if (Key == "text") {
2134         Entry.Text = std::string(Val);
2135       }
2136     }
2137 
2138     if (!Ignore)
2139       Entries.push_back(Entry);
2140   }
2141 };
2142 } // end anonymous namespace
2143 
2144 static bool reportDiag(const Twine &Err, DiagnosticsEngine &Diag) {
2145   Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
2146       << Err.str();
2147   return true;
2148 }
2149 
2150 static std::string applyEditsToTemp(FileEntryRef FE,
2151                                     ArrayRef<EditEntry> Edits,
2152                                     FileManager &FileMgr,
2153                                     DiagnosticsEngine &Diag) {
2154   using namespace llvm::sys;
2155 
2156   SourceManager SM(Diag, FileMgr);
2157   FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
2158   LangOptions LangOpts;
2159   edit::EditedSource Editor(SM, LangOpts);
2160   for (ArrayRef<EditEntry>::iterator
2161         I = Edits.begin(), E = Edits.end(); I != E; ++I) {
2162     const EditEntry &Entry = *I;
2163     assert(Entry.File == FE);
2164     SourceLocation Loc =
2165         SM.getLocForStartOfFile(FID).getLocWithOffset(Entry.Offset);
2166     CharSourceRange Range;
2167     if (Entry.RemoveLen != 0) {
2168       Range = CharSourceRange::getCharRange(Loc,
2169                                          Loc.getLocWithOffset(Entry.RemoveLen));
2170     }
2171 
2172     edit::Commit commit(Editor);
2173     if (Range.isInvalid()) {
2174       commit.insert(Loc, Entry.Text);
2175     } else if (Entry.Text.empty()) {
2176       commit.remove(Range);
2177     } else {
2178       commit.replace(Range, Entry.Text);
2179     }
2180     Editor.commit(commit);
2181   }
2182 
2183   Rewriter rewriter(SM, LangOpts);
2184   RewritesReceiver Rec(rewriter);
2185   Editor.applyRewrites(Rec, /*adjustRemovals=*/false);
2186 
2187   const RewriteBuffer *Buf = rewriter.getRewriteBufferFor(FID);
2188   SmallString<512> NewText;
2189   llvm::raw_svector_ostream OS(NewText);
2190   Buf->write(OS);
2191 
2192   SmallString<64> TempPath;
2193   int FD;
2194   if (fs::createTemporaryFile(path::filename(FE.getName()),
2195                               path::extension(FE.getName()).drop_front(), FD,
2196                               TempPath)) {
2197     reportDiag("Could not create file: " + TempPath.str(), Diag);
2198     return std::string();
2199   }
2200 
2201   llvm::raw_fd_ostream TmpOut(FD, /*shouldClose=*/true);
2202   TmpOut.write(NewText.data(), NewText.size());
2203   TmpOut.close();
2204 
2205   return std::string(TempPath);
2206 }
2207 
2208 bool arcmt::getFileRemappingsFromFileList(
2209                         std::vector<std::pair<std::string,std::string> > &remap,
2210                         ArrayRef<StringRef> remapFiles,
2211                         DiagnosticConsumer *DiagClient) {
2212   bool hasErrorOccurred = false;
2213 
2214   FileSystemOptions FSOpts;
2215   FileManager FileMgr(FSOpts);
2216   RemapFileParser Parser(FileMgr);
2217 
2218   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
2219   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
2220       new DiagnosticsEngine(DiagID, new DiagnosticOptions,
2221                             DiagClient, /*ShouldOwnClient=*/false));
2222 
2223   typedef llvm::DenseMap<FileEntryRef, std::vector<EditEntry> >
2224       FileEditEntriesTy;
2225   FileEditEntriesTy FileEditEntries;
2226 
2227   llvm::DenseSet<EditEntry> EntriesSet;
2228 
2229   for (ArrayRef<StringRef>::iterator
2230          I = remapFiles.begin(), E = remapFiles.end(); I != E; ++I) {
2231     SmallVector<EditEntry, 16> Entries;
2232     if (Parser.parse(*I, Entries))
2233       continue;
2234 
2235     for (SmallVectorImpl<EditEntry>::iterator
2236            EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) {
2237       EditEntry &Entry = *EI;
2238       if (!Entry.File)
2239         continue;
2240       std::pair<llvm::DenseSet<EditEntry>::iterator, bool>
2241         Insert = EntriesSet.insert(Entry);
2242       if (!Insert.second)
2243         continue;
2244 
2245       FileEditEntries[*Entry.File].push_back(Entry);
2246     }
2247   }
2248 
2249   for (FileEditEntriesTy::iterator
2250          I = FileEditEntries.begin(), E = FileEditEntries.end(); I != E; ++I) {
2251     std::string TempFile = applyEditsToTemp(I->first, I->second,
2252                                             FileMgr, *Diags);
2253     if (TempFile.empty()) {
2254       hasErrorOccurred = true;
2255       continue;
2256     }
2257 
2258     remap.emplace_back(std::string(I->first.getName()), TempFile);
2259   }
2260 
2261   return hasErrorOccurred;
2262 }
2263