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