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