diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 |
commit | 9f4dbff6669c8037f3b036bcf580d14f1a4f12a5 (patch) | |
tree | 47df2c12b57214af6c31e47404b005675b8b7ffc /lib/ARCMigrate | |
parent | f73d5f23a889b93d89ddef61ac0995df40286bb8 (diff) | |
download | src-9f4dbff6669c8037f3b036bcf580d14f1a4f12a5.tar.gz src-9f4dbff6669c8037f3b036bcf580d14f1a4f12a5.zip |
Vendor import of clang RELEASE_350/final tag r216957 (effectively, 3.5.0 release):vendor/clang/clang-release_350-r216957
Notes
Notes:
svn path=/vendor/clang/dist/; revision=274958
svn path=/vendor/clang/clang-release_350-r216957/; revision=274959; tag=vendor/clang/clang-release_350-r216957
Diffstat (limited to 'lib/ARCMigrate')
-rw-r--r-- | lib/ARCMigrate/ARCMT.cpp | 87 | ||||
-rw-r--r-- | lib/ARCMigrate/CMakeLists.txt | 30 | ||||
-rw-r--r-- | lib/ARCMigrate/FileRemapper.cpp | 43 | ||||
-rw-r--r-- | lib/ARCMigrate/Internals.h | 9 | ||||
-rw-r--r-- | lib/ARCMigrate/ObjCMT.cpp | 710 | ||||
-rw-r--r-- | lib/ARCMigrate/PlistReporter.cpp | 113 | ||||
-rw-r--r-- | lib/ARCMigrate/TransAPIUses.cpp | 16 | ||||
-rw-r--r-- | lib/ARCMigrate/TransAutoreleasePool.cpp | 8 | ||||
-rw-r--r-- | lib/ARCMigrate/TransBlockObjCVariable.cpp | 7 | ||||
-rw-r--r-- | lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp | 24 | ||||
-rw-r--r-- | lib/ARCMigrate/TransGCAttrs.cpp | 12 | ||||
-rw-r--r-- | lib/ARCMigrate/TransGCCalls.cpp | 10 | ||||
-rw-r--r-- | lib/ARCMigrate/TransProperties.cpp | 31 | ||||
-rw-r--r-- | lib/ARCMigrate/TransProtectedScope.cpp | 2 | ||||
-rw-r--r-- | lib/ARCMigrate/TransRetainReleaseDealloc.cpp | 18 | ||||
-rw-r--r-- | lib/ARCMigrate/TransUnbridgedCasts.cpp | 15 | ||||
-rw-r--r-- | lib/ARCMigrate/TransUnusedInitDelegate.cpp | 2 | ||||
-rw-r--r-- | lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp | 34 | ||||
-rw-r--r-- | lib/ARCMigrate/TransformActions.cpp | 64 | ||||
-rw-r--r-- | lib/ARCMigrate/Transforms.cpp | 23 | ||||
-rw-r--r-- | lib/ARCMigrate/Transforms.h | 12 |
21 files changed, 712 insertions, 558 deletions
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp index 3e429beded5d..8a13b2ee4f1d 100644 --- a/lib/ARCMigrate/ARCMT.cpp +++ b/lib/ARCMigrate/ARCMT.cpp @@ -103,8 +103,8 @@ public: : Diags(diags), DiagClient(client), CapturedDiags(capturedDiags), HasBegunSourceFile(false) { } - virtual void BeginSourceFile(const LangOptions &Opts, - const Preprocessor *PP) { + void BeginSourceFile(const LangOptions &Opts, + const Preprocessor *PP) override { // Pass BeginSourceFile message onto DiagClient on first call. // The corresponding EndSourceFile call will be made from an // explicit call to FinishCapture. @@ -128,8 +128,8 @@ public: assert(!HasBegunSourceFile && "FinishCapture not called!"); } - virtual void HandleDiagnostic(DiagnosticsEngine::Level level, - const Diagnostic &Info) { + void HandleDiagnostic(DiagnosticsEngine::Level level, + const Diagnostic &Info) override { if (DiagnosticIDs::isARCDiagnostic(Info.getID()) || level >= DiagnosticsEngine::Error || level == DiagnosticsEngine::Note) { if (Info.getLocation().isValid()) @@ -167,7 +167,7 @@ static bool HasARCRuntime(CompilerInvocation &origCI) { static CompilerInvocation * createInvocationForMigration(CompilerInvocation &origCI) { - OwningPtr<CompilerInvocation> CInvok; + std::unique_ptr<CompilerInvocation> CInvok; CInvok.reset(new CompilerInvocation(origCI)); PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts(); if (!PPOpts.ImplicitPCHInclude.empty()) { @@ -204,11 +204,11 @@ createInvocationForMigration(CompilerInvocation &origCI) { WarnOpts.push_back(*I); } WarnOpts.push_back("error=arc-unsafe-retained-assign"); - CInvok->getDiagnosticOpts().Warnings = llvm_move(WarnOpts); + CInvok->getDiagnosticOpts().Warnings = std::move(WarnOpts); CInvok->getLangOpts()->ObjCARCWeak = HasARCRuntime(origCI); - return CInvok.take(); + return CInvok.release(); } static void emitPremigrationErrors(const CapturedDiagList &arcDiags, @@ -246,7 +246,7 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI, NoFinalizeRemoval); assert(!transforms.empty()); - OwningPtr<CompilerInvocation> CInvok; + std::unique_ptr<CompilerInvocation> CInvok; CInvok.reset(createInvocationForMigration(origCI)); CInvok->getFrontendOpts().Inputs.clear(); CInvok->getFrontendOpts().Inputs.push_back(Input); @@ -263,8 +263,8 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI, CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags); Diags->setClient(&errRec, /*ShouldOwnClient=*/false); - OwningPtr<ASTUnit> Unit( - ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags)); + std::unique_ptr<ASTUnit> Unit( + ASTUnit::LoadFromCompilerInvocationAction(CInvok.release(), Diags)); if (!Unit) { errRec.FinishCapture(); return true; @@ -310,8 +310,10 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI, TransformActions testAct(*Diags, capturedDiags, Ctx, Unit->getPreprocessor()); MigrationPass pass(Ctx, OrigGCMode, Unit->getSema(), testAct, capturedDiags, ARCMTMacroLocs); - pass.setNSAllocReallocError(NoNSAllocReallocError); pass.setNoFinalizeRemoval(NoFinalizeRemoval); + if (!NoNSAllocReallocError) + Diags->setSeverity(diag::warn_arcmt_nsalloc_realloc, diag::Severity::Error, + SourceLocation()); for (unsigned i=0, e = transforms.size(); i != e; ++i) transforms[i](pass); @@ -416,44 +418,6 @@ bool arcmt::getFileRemappings(std::vector<std::pair<std::string,std::string> > & return false; } -bool arcmt::getFileRemappingsFromFileList( - std::vector<std::pair<std::string,std::string> > &remap, - ArrayRef<StringRef> remapFiles, - DiagnosticConsumer *DiagClient) { - bool hasErrorOccurred = false; - llvm::StringMap<bool> Uniquer; - - IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr<DiagnosticsEngine> Diags( - new DiagnosticsEngine(DiagID, new DiagnosticOptions, - DiagClient, /*ShouldOwnClient=*/false)); - - for (ArrayRef<StringRef>::iterator - I = remapFiles.begin(), E = remapFiles.end(); I != E; ++I) { - StringRef file = *I; - - FileRemapper remapper; - bool err = remapper.initFromFile(file, *Diags, - /*ignoreIfFilesChanged=*/true); - hasErrorOccurred = hasErrorOccurred || err; - if (err) - continue; - - PreprocessorOptions PPOpts; - remapper.applyMappings(PPOpts); - for (PreprocessorOptions::remapped_file_iterator - RI = PPOpts.remapped_file_begin(), RE = PPOpts.remapped_file_end(); - RI != RE; ++RI) { - bool &inserted = Uniquer[RI->first]; - if (inserted) - continue; - inserted = true; - remap.push_back(*RI); - } - } - - return hasErrorOccurred; -} //===----------------------------------------------------------------------===// // CollectTransformActions. @@ -468,8 +432,8 @@ public: ARCMTMacroTrackerPPCallbacks(std::vector<SourceLocation> &ARCMTMacroLocs) : ARCMTMacroLocs(ARCMTMacroLocs) { } - virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, - SourceRange Range, const MacroArgs *Args) { + void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, + SourceRange Range, const MacroArgs *Args) override { if (MacroNameTok.getIdentifierInfo()->getName() == getARCMTMacroName()) ARCMTMacroLocs.push_back(MacroNameTok.getLocation()); } @@ -482,8 +446,8 @@ public: ARCMTMacroTrackerAction(std::vector<SourceLocation> &ARCMTMacroLocs) : ARCMTMacroLocs(ARCMTMacroLocs) { } - virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { + ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override { CI.getPreprocessor().addPPCallbacks( new ARCMTMacroTrackerPPCallbacks(ARCMTMacroLocs)); return new ASTConsumer(); @@ -506,14 +470,14 @@ public: Listener->finish(); } - virtual void insert(SourceLocation loc, StringRef text) { + void insert(SourceLocation loc, StringRef text) override { bool err = rewriter.InsertText(loc, text, /*InsertAfter=*/true, /*indentNewLines=*/true); if (!err && Listener) Listener->insert(loc, text); } - virtual void remove(CharSourceRange range) { + void remove(CharSourceRange range) override { Rewriter::RewriteOptions removeOpts; removeOpts.IncludeInsertsAtBeginOfRange = false; removeOpts.IncludeInsertsAtEndOfRange = false; @@ -524,8 +488,8 @@ public: Listener->remove(range); } - virtual void increaseIndentation(CharSourceRange range, - SourceLocation parentIndent) { + void increaseIndentation(CharSourceRange range, + SourceLocation parentIndent) override { rewriter.IncreaseIndentation(range, parentIndent); } }; @@ -550,7 +514,7 @@ MigrationProcess::MigrationProcess(const CompilerInvocation &CI, bool MigrationProcess::applyTransform(TransformFn trans, RewriteListener *listener) { - OwningPtr<CompilerInvocation> CInvok; + std::unique_ptr<CompilerInvocation> CInvok; CInvok.reset(createInvocationForMigration(OrigCI)); CInvok->getDiagnosticOpts().IgnoreWarnings = true; @@ -569,12 +533,11 @@ bool MigrationProcess::applyTransform(TransformFn trans, CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags); Diags->setClient(&errRec, /*ShouldOwnClient=*/false); - OwningPtr<ARCMTMacroTrackerAction> ASTAction; + std::unique_ptr<ARCMTMacroTrackerAction> ASTAction; ASTAction.reset(new ARCMTMacroTrackerAction(ARCMTMacroLocs)); - OwningPtr<ASTUnit> Unit( - ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags, - ASTAction.get())); + std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCompilerInvocationAction( + CInvok.release(), Diags, ASTAction.get())); if (!Unit) { errRec.FinishCapture(); return true; diff --git a/lib/ARCMigrate/CMakeLists.txt b/lib/ARCMigrate/CMakeLists.txt index c55261277dd1..b716a20fe63f 100644 --- a/lib/ARCMigrate/CMakeLists.txt +++ b/lib/ARCMigrate/CMakeLists.txt @@ -1,3 +1,7 @@ +set(LLVM_LINK_COMPONENTS + Support + ) + add_clang_library(clangARCMigrate ARCMT.cpp ARCMTActions.cpp @@ -19,26 +23,16 @@ add_clang_library(clangARCMigrate TransZeroOutPropsInDealloc.cpp TransformActions.cpp Transforms.cpp - ) -add_dependencies(clangARCMigrate - ClangAttrClasses - ClangAttrList - ClangAttrParsedAttrList - ClangCommentNodes - ClangDeclNodes - ClangDiagnosticCommon - ClangDiagnosticGroups - ClangDiagnosticSema - ClangStmtNodes - ) - -target_link_libraries(clangARCMigrate - clangBasic + LINK_LIBS clangAST - clangParse + clangAnalysis + clangBasic + clangEdit clangFrontend - clangRewriteCore - clangRewriteFrontend + clangLex + clangRewrite + clangSema + clangSerialization clangStaticAnalyzerCheckers ) diff --git a/lib/ARCMigrate/FileRemapper.cpp b/lib/ARCMigrate/FileRemapper.cpp index a14226e43fe0..40e606090064 100644 --- a/lib/ARCMigrate/FileRemapper.cpp +++ b/lib/ARCMigrate/FileRemapper.cpp @@ -36,8 +36,7 @@ void FileRemapper::clear(StringRef outputDir) { assert(ToFromMappings.empty()); if (!outputDir.empty()) { std::string infoFile = getRemapInfoFile(outputDir); - bool existed; - llvm::sys::fs::remove(infoFile, existed); + llvm::sys::fs::remove(infoFile); } } @@ -65,13 +64,14 @@ bool FileRemapper::initFromFile(StringRef filePath, DiagnosticsEngine &Diag, return false; std::vector<std::pair<const FileEntry *, const FileEntry *> > pairs; - - OwningPtr<llvm::MemoryBuffer> fileBuf; - if (llvm::MemoryBuffer::getFile(infoFile.c_str(), fileBuf)) + + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBuf = + llvm::MemoryBuffer::getFile(infoFile.c_str()); + if (!fileBuf) return report("Error opening file: " + infoFile, Diag); SmallVector<StringRef, 64> lines; - fileBuf->getBuffer().split(lines, "\n"); + fileBuf.get()->getBuffer().split(lines, "\n"); for (unsigned idx = 0; idx+3 <= lines.size(); idx += 3) { StringRef fromFilename = lines[idx]; @@ -112,8 +112,7 @@ bool FileRemapper::initFromFile(StringRef filePath, DiagnosticsEngine &Diag, bool FileRemapper::flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag) { using namespace llvm::sys; - bool existed; - if (fs::create_directory(outputDir, existed) != llvm::errc::success) + if (fs::create_directory(outputDir)) return report("Could not create directory: " + outputDir, Diag); std::string infoFile = getRemapInfoFile(outputDir); @@ -125,8 +124,7 @@ bool FileRemapper::flushToFile(StringRef outputPath, DiagnosticsEngine &Diag) { std::string errMsg; std::string infoFile = outputPath; - llvm::raw_fd_ostream infoOut(infoFile.c_str(), errMsg, - llvm::sys::fs::F_Binary); + llvm::raw_fd_ostream infoOut(infoFile.c_str(), errMsg, llvm::sys::fs::F_None); if (!errMsg.empty()) return report(errMsg, Diag); @@ -182,8 +180,7 @@ bool FileRemapper::overwriteOriginal(DiagnosticsEngine &Diag, Diag); std::string errMsg; - llvm::raw_fd_ostream Out(origFE->getName(), errMsg, - llvm::sys::fs::F_Binary); + llvm::raw_fd_ostream Out(origFE->getName(), errMsg, llvm::sys::fs::F_None); if (!errMsg.empty()) return report(errMsg, Diag); @@ -210,22 +207,6 @@ void FileRemapper::applyMappings(PreprocessorOptions &PPOpts) const { PPOpts.RetainRemappedFileBuffers = true; } -void FileRemapper::transferMappingsAndClear(PreprocessorOptions &PPOpts) { - for (MappingsTy::iterator - I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) { - if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) { - PPOpts.addRemappedFile(I->first->getName(), FE->getName()); - } else { - llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>(); - PPOpts.addRemappedFile(I->first->getName(), mem); - } - I->second = Target(); - } - - PPOpts.RetainRemappedFileBuffers = false; - clear(); -} - void FileRemapper::remap(StringRef filePath, llvm::MemoryBuffer *memBuf) { remap(getOriginalFile(filePath), memBuf); } @@ -272,9 +253,7 @@ void FileRemapper::resetTarget(Target &targ) { } bool FileRemapper::report(const Twine &err, DiagnosticsEngine &Diag) { - SmallString<128> buf; - unsigned ID = Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Error, - err.toStringRef(buf)); - Diag.Report(ID); + Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0")) + << err.str(); return true; } diff --git a/lib/ARCMigrate/Internals.h b/lib/ARCMigrate/Internals.h index 3690c83d8457..a65b329c5b03 100644 --- a/lib/ARCMigrate/Internals.h +++ b/lib/ARCMigrate/Internals.h @@ -48,7 +48,6 @@ void writeARCDiagsToPlist(const std::string &outPath, class TransformActions { DiagnosticsEngine &Diags; CapturedDiagList &CapturedDiags; - bool ReportedErrors; void *Impl; // TransformActionsImpl. public: @@ -95,6 +94,8 @@ public: return CapturedDiags.hasDiagnostic(IDs, range); } + DiagnosticBuilder report(SourceLocation loc, unsigned diagId, + SourceRange range = SourceRange()); void reportError(StringRef error, SourceLocation loc, SourceRange range = SourceRange()); void reportWarning(StringRef warning, SourceLocation loc, @@ -102,7 +103,9 @@ public: void reportNote(StringRef note, SourceLocation loc, SourceRange range = SourceRange()); - bool hasReportedErrors() const { return ReportedErrors; } + bool hasReportedErrors() const { + return Diags.hasUnrecoverableErrorOccurred(); + } class RewriteReceiver { public: @@ -161,8 +164,6 @@ public: const CapturedDiagList &getDiags() const { return CapturedDiags; } bool isGCMigration() const { return OrigGCMode != LangOptions::NonGC; } - bool noNSAllocReallocError() const { return MigOptions.NoNSAllocReallocError; } - void setNSAllocReallocError(bool val) { MigOptions.NoNSAllocReallocError = val; } bool noFinalizeRemoval() const { return MigOptions.NoFinalizeRemoval; } void setNoFinalizeRemoval(bool val) {MigOptions.NoFinalizeRemoval = val; } diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index cac0fb0aed1b..1a2055e9c452 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -8,12 +8,15 @@ //===----------------------------------------------------------------------===// #include "Transforms.h" +#include "clang/ARCMigrate/ARCMT.h" #include "clang/ARCMigrate/ARCMTActions.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" #include "clang/AST/NSAPI.h" #include "clang/AST/ParentMap.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Analysis/DomainSpecific/CocoaConventions.h" #include "clang/Basic/FileManager.h" #include "clang/Edit/Commit.h" #include "clang/Edit/EditedSource.h" @@ -24,11 +27,11 @@ #include "clang/Lex/PPConditionalDirectiveRecord.h" #include "clang/Lex/Preprocessor.h" #include "clang/Rewrite/Core/Rewriter.h" -#include "clang/Analysis/DomainSpecific/CocoaConventions.h" #include "clang/StaticAnalyzer/Checkers/ObjCRetainCount.h" -#include "clang/AST/Attr.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Path.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/YAMLParser.h" using namespace clang; using namespace arcmt; @@ -45,7 +48,6 @@ class ObjCMigrateASTConsumer : public ASTConsumer { void migrateDecl(Decl *D); void migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCContainerDecl *D); - void migrateDeprecatedAnnotation(ASTContext &Ctx, ObjCCategoryDecl *CatDecl); void migrateProtocolConformance(ASTContext &Ctx, const ObjCImplementationDecl *ImpDecl); void CacheObjCNSIntegerTypedefed(const TypedefDecl *TypedefDcl); @@ -76,14 +78,18 @@ class ObjCMigrateASTConsumer : public ASTConsumer { void migrateAddMethodAnnotation(ASTContext &Ctx, const ObjCMethodDecl *MethodDecl); + + void inferDesignatedInitializers(ASTContext &Ctx, + const ObjCImplementationDecl *ImplD); + public: std::string MigrateDir; unsigned ASTMigrateActions; FileID FileId; const TypedefDecl *NSIntegerTypedefed; const TypedefDecl *NSUIntegerTypedefed; - OwningPtr<NSAPI> NSAPIObj; - OwningPtr<edit::EditedSource> Editor; + std::unique_ptr<NSAPI> NSAPIObj; + std::unique_ptr<edit::EditedSource> Editor; FileRemapper &Remapper; FileManager &FileMgr; const PPConditionalDirectiveRecord *PPRec; @@ -103,7 +109,7 @@ public: ArrayRef<std::string> WhiteList) : MigrateDir(migrateDir), ASTMigrateActions(astMigrateActions), - NSIntegerTypedefed(0), NSUIntegerTypedefed(0), + NSIntegerTypedefed(nullptr), NSUIntegerTypedefed(nullptr), Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP), IsOutputFile(isOutputFile) { @@ -114,26 +120,26 @@ public: } protected: - virtual void Initialize(ASTContext &Context) { + void Initialize(ASTContext &Context) override { NSAPIObj.reset(new NSAPI(Context)); Editor.reset(new edit::EditedSource(Context.getSourceManager(), Context.getLangOpts(), - PPRec, false)); + PPRec)); } - virtual bool HandleTopLevelDecl(DeclGroupRef DG) { + bool HandleTopLevelDecl(DeclGroupRef DG) override { for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) migrateDecl(*I); return true; } - virtual void HandleInterestingDecl(DeclGroupRef DG) { + void HandleInterestingDecl(DeclGroupRef DG) override { // Ignore decls from the PCH. } - virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) { + void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override { ObjCMigrateASTConsumer::HandleTopLevelDecl(DG); } - virtual void HandleTranslationUnit(ASTContext &Ctx); + void HandleTranslationUnit(ASTContext &Ctx) override; bool canModifyFile(StringRef Path) { if (WhiteListFilenames.empty()) @@ -141,6 +147,30 @@ protected: return WhiteListFilenames.find(llvm::sys::path::filename(Path)) != WhiteListFilenames.end(); } + bool canModifyFile(const FileEntry *FE) { + if (!FE) + return false; + return canModifyFile(FE->getName()); + } + bool canModifyFile(FileID FID) { + if (FID.isInvalid()) + return false; + return canModifyFile(PP.getSourceManager().getFileEntryForID(FID)); + } + + bool canModify(const Decl *D) { + if (!D) + return false; + if (const ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(D)) + return canModify(CatImpl->getCategoryDecl()); + if (const ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) + return canModify(Impl->getClassInterface()); + if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) + return canModify(cast<Decl>(MD->getDeclContext())); + + FileID FID = PP.getSourceManager().getFileID(D->getLocation()); + return canModifyFile(FID); + } }; } @@ -150,7 +180,7 @@ ObjCMigrateAction::ObjCMigrateAction(FrontendAction *WrappedAction, unsigned migrateAction) : WrapperFrontendAction(WrappedAction), MigrateDir(migrateDir), ObjCMigAction(migrateAction), - CompInst(0) { + CompInst(nullptr) { if (MigrateDir.empty()) MigrateDir = "."; // user current directory if none is given. } @@ -223,7 +253,7 @@ public: class BodyMigrator : public RecursiveASTVisitor<BodyMigrator> { ObjCMigrateASTConsumer &Consumer; - OwningPtr<ParentMap> PMap; + std::unique_ptr<ParentMap> PMap; public: BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { } @@ -294,7 +324,9 @@ void MigrateBlockOrFunctionPointerTypeVariable(std::string & PropertyString, static const char *PropertyMemoryAttribute(ASTContext &Context, QualType ArgType) { Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime(); bool RetainableObject = ArgType->isObjCRetainableType(); - if (RetainableObject && propertyLifetime == Qualifiers::OCL_Strong) { + if (RetainableObject && + (propertyLifetime == Qualifiers::OCL_Strong + || propertyLifetime == Qualifiers::OCL_None)) { if (const ObjCObjectPointerType *ObjPtrTy = ArgType->getAs<ObjCObjectPointerType>()) { ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface(); @@ -302,7 +334,7 @@ static const char *PropertyMemoryAttribute(ASTContext &Context, QualType ArgType IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying"))) return "copy"; else - return "retain"; + return "strong"; } else if (ArgType->isBlockPointerType()) return "copy"; @@ -311,8 +343,8 @@ static const char *PropertyMemoryAttribute(ASTContext &Context, QualType ArgType // looking into setter's implementation for backing weak ivar. return "weak"; else if (RetainableObject) - return ArgType->isBlockPointerType() ? "copy" : "retain"; - return 0; + return ArgType->isBlockPointerType() ? "copy" : "strong"; + return nullptr; } static void rewriteToObjCProperty(const ObjCMethodDecl *Getter, @@ -344,23 +376,23 @@ static void rewriteToObjCProperty(const ObjCMethodDecl *Getter, PropertyString += PropertyNameString; } // Property with no setter may be suggested as a 'readonly' property. - if (!Setter) { + if (!Setter) append_attr(PropertyString, "readonly", LParenAdded); - QualType ResType = Context.getCanonicalType(Getter->getResultType()); - if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ResType)) - append_attr(PropertyString, MemoryManagementAttr, LParenAdded); - } + // Short circuit 'delegate' properties that contain the name "delegate" or // "dataSource", or have exact name "target" to have 'assign' attribute. if (PropertyName.equals("target") || (PropertyName.find("delegate") != StringRef::npos) || (PropertyName.find("dataSource") != StringRef::npos)) { - QualType QT = Getter->getResultType(); + QualType QT = Getter->getReturnType(); if (!QT->isRealType()) append_attr(PropertyString, "assign", LParenAdded); - } - else if (Setter) { + } else if (!Setter) { + QualType ResType = Context.getCanonicalType(Getter->getReturnType()); + if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ResType)) + append_attr(PropertyString, MemoryManagementAttr, LParenAdded); + } else { const ParmVarDecl *argDecl = *Setter->param_begin(); QualType ArgType = Context.getCanonicalType(argDecl->getType()); if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ArgType)) @@ -368,7 +400,7 @@ static void rewriteToObjCProperty(const ObjCMethodDecl *Getter, } if (LParenAdded) PropertyString += ')'; - QualType RT = Getter->getResultType(); + QualType RT = Getter->getReturnType(); if (!isa<TypedefType>(RT)) { // strip off any ARC lifetime qualifier. QualType CanResultTy = Context.getCanonicalType(RT); @@ -419,21 +451,27 @@ static void rewriteToObjCProperty(const ObjCMethodDecl *Getter, // Get location past ';' EndLoc = EndLoc.getLocWithOffset(1); SourceLocation BeginOfSetterDclLoc = Setter->getLocStart(); - // FIXME. This assumes that setter decl; is immediately preceeded by eoln. + // FIXME. This assumes that setter decl; is immediately preceded by eoln. // It is trying to remove the setter method decl. line entirely. BeginOfSetterDclLoc = BeginOfSetterDclLoc.getLocWithOffset(-1); commit.remove(SourceRange(BeginOfSetterDclLoc, EndLoc)); } } +static bool IsCategoryNameWithDeprecatedSuffix(ObjCContainerDecl *D) { + if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(D)) { + StringRef Name = CatDecl->getName(); + return Name.endswith("Deprecated"); + } + return false; +} + void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCContainerDecl *D) { - if (D->isDeprecated()) + if (D->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(D)) return; - - for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end(); - M != MEnd; ++M) { - ObjCMethodDecl *Method = (*M); + + for (auto *Method : D->methods()) { if (Method->isDeprecated()) continue; bool PropertyInferred = migrateProperty(Ctx, D, Method); @@ -448,48 +486,13 @@ void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx, if (!(ASTMigrateActions & FrontendOptions::ObjCMT_ReturnsInnerPointerProperty)) return; - for (ObjCContainerDecl::prop_iterator P = D->prop_begin(), - E = D->prop_end(); P != E; ++P) { - ObjCPropertyDecl *Prop = *P; + for (auto *Prop : D->properties()) { if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) && !Prop->isDeprecated()) migratePropertyNsReturnsInnerPointer(Ctx, Prop); } } -void ObjCMigrateASTConsumer::migrateDeprecatedAnnotation(ASTContext &Ctx, - ObjCCategoryDecl *CatDecl) { - StringRef Name = CatDecl->getName(); - if (!Name.endswith("Deprecated")) - return; - - if (!Ctx.Idents.get("DEPRECATED").hasMacroDefinition()) - return; - - ObjCContainerDecl *D = cast<ObjCContainerDecl>(CatDecl); - - for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end(); - M != MEnd; ++M) { - ObjCMethodDecl *Method = (*M); - if (Method->isDeprecated() || Method->isImplicit()) - continue; - // Annotate with DEPRECATED - edit::Commit commit(*Editor); - commit.insertBefore(Method->getLocEnd(), " DEPRECATED"); - Editor->commit(commit); - } - for (ObjCContainerDecl::prop_iterator P = D->prop_begin(), - E = D->prop_end(); P != E; ++P) { - ObjCPropertyDecl *Prop = *P; - if (Prop->isDeprecated()) - continue; - // Annotate with DEPRECATED - edit::Commit commit(*Editor); - commit.insertAfterToken(Prop->getLocEnd(), " DEPRECATED"); - Editor->commit(commit); - } -} - static bool ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, const ObjCImplementationDecl *ImpDecl, @@ -500,9 +503,7 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, // in class interface. bool HasAtleastOneRequiredProperty = false; if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) - for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), - E = PDecl->prop_end(); P != E; ++P) { - ObjCPropertyDecl *Property = *P; + for (const auto *Property : PDecl->properties()) { if (Property->getPropertyImplementation() == ObjCPropertyDecl::Optional) continue; HasAtleastOneRequiredProperty = true; @@ -532,9 +533,7 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) { if (PDecl->meth_begin() == PDecl->meth_end()) return HasAtleastOneRequiredProperty; - for (ObjCContainerDecl::method_iterator M = PDecl->meth_begin(), - MEnd = PDecl->meth_end(); M != MEnd; ++M) { - ObjCMethodDecl *MD = (*M); + for (const auto *MD : PDecl->methods()) { if (MD->isImplicit()) continue; if (MD->getImplementationControl() == ObjCMethodDecl::Optional) @@ -632,7 +631,7 @@ static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl, /*IsDecl*/true); if (!EndOfEnumDclLoc.isInvalid()) { SourceLocation BeginOfEnumDclLoc = EnumDcl->getLocStart(); - // FIXME. This assumes that enum decl; is immediately preceeded by eoln. + // FIXME. This assumes that enum decl; is immediately preceded by eoln. // It is trying to remove the enum decl. lines entirely. BeginOfEnumDclLoc = BeginOfEnumDclLoc.getLocWithOffset(-1); commit.remove(SourceRange(BeginOfEnumDclLoc, EndOfEnumDclLoc)); @@ -660,9 +659,7 @@ static bool UseNSOptionsMacro(Preprocessor &PP, ASTContext &Ctx, bool PowerOfTwo = true; bool AllHexdecimalEnumerator = true; uint64_t MaxPowerOfTwoVal = 0; - for (EnumDecl::enumerator_iterator EI = EnumDcl->enumerator_begin(), - EE = EnumDcl->enumerator_end(); EI != EE; ++EI) { - EnumConstantDecl *Enumerator = (*EI); + for (auto Enumerator : EnumDcl->enumerators()) { const Expr *InitExpr = Enumerator->getInitExpr(); if (!InitExpr) { PowerOfTwo = false; @@ -749,6 +746,8 @@ void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx, if (!DropIt) MinimalConformingProtocols.push_back(TargetPDecl); } + if (MinimalConformingProtocols.empty()) + return; edit::Commit commit(*Editor); rewriteToObjCInterfaceDecl(IDecl, MinimalConformingProtocols, *NSAPIObj, commit); @@ -774,11 +773,11 @@ bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx, if (!TypedefDcl) { if (NSIntegerTypedefed) { TypedefDcl = NSIntegerTypedefed; - NSIntegerTypedefed = 0; + NSIntegerTypedefed = nullptr; } else if (NSUIntegerTypedefed) { TypedefDcl = NSUIntegerTypedefed; - NSUIntegerTypedefed = 0; + NSUIntegerTypedefed = nullptr; } else return false; @@ -831,11 +830,15 @@ bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx, return Res; } -static void ReplaceWithInstancetype(const ObjCMigrateASTConsumer &ASTC, +static void ReplaceWithInstancetype(ASTContext &Ctx, + const ObjCMigrateASTConsumer &ASTC, ObjCMethodDecl *OM) { + if (OM->getReturnType() == Ctx.getObjCInstanceType()) + return; // already has instancetype. + SourceRange R; std::string ClassString; - if (TypeSourceInfo *TSInfo = OM->getResultTypeSourceInfo()) { + if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) { TypeLoc TL = TSInfo->getTypeLoc(); R = SourceRange(TL.getBeginLoc(), TL.getEndLoc()); ClassString = "instancetype"; @@ -855,7 +858,7 @@ static void ReplaceWithClasstype(const ObjCMigrateASTConsumer &ASTC, ObjCInterfaceDecl *IDecl = OM->getClassInterface(); SourceRange R; std::string ClassString; - if (TypeSourceInfo *TSInfo = OM->getResultTypeSourceInfo()) { + if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) { TypeLoc TL = TSInfo->getTypeLoc(); R = SourceRange(TL.getBeginLoc(), TL.getEndLoc()); { ClassString = IDecl->getName(); @@ -893,14 +896,14 @@ void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx, migrateFactoryMethod(Ctx, CDecl, OM, OIT_Singleton); return; case OIT_Init: - if (OM->getResultType()->isObjCIdType()) - ReplaceWithInstancetype(*this, OM); + if (OM->getReturnType()->isObjCIdType()) + ReplaceWithInstancetype(Ctx, *this, OM); return; case OIT_ReturnsSelf: migrateFactoryMethod(Ctx, CDecl, OM, OIT_ReturnsSelf); return; } - if (!OM->getResultType()->isObjCIdType()) + if (!OM->getReturnType()->isObjCIdType()) return; ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl); @@ -915,7 +918,7 @@ void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx, migrateFactoryMethod(Ctx, CDecl, OM); return; } - ReplaceWithInstancetype(*this, OM); + ReplaceWithInstancetype(Ctx, *this, OM); } static bool TypeIsInnerPointer(QualType T) { @@ -1034,7 +1037,7 @@ bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx, Method->param_size() != 0) return false; // Is this method candidate to be a getter? - QualType GRT = Method->getResultType(); + QualType GRT = Method->getReturnType(); if (GRT->isVoidType()) return false; @@ -1087,7 +1090,7 @@ bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx, return false; // Is this a valid setter, matching the target getter? - QualType SRT = SetterMethod->getResultType(); + QualType SRT = SetterMethod->getReturnType(); if (!SRT->isVoidType()) return false; const ParmVarDecl *argDecl = *SetterMethod->param_begin(); @@ -1109,7 +1112,7 @@ bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx, // Try a non-void method with no argument (and no setter or property of same name // as a 'readonly' property. edit::Commit commit(*Editor); - rewriteToObjCProperty(Method, 0 /*SetterMethod*/, *NSAPIObj, commit, + rewriteToObjCProperty(Method, nullptr /*SetterMethod*/, *NSAPIObj, commit, LengthOfPrefix, (ASTMigrateActions & FrontendOptions::ObjCMT_AtomicProperty) != 0, @@ -1128,8 +1131,8 @@ void ObjCMigrateASTConsumer::migrateNsReturnsInnerPointer(ASTContext &Ctx, !OM->isInstanceMethod() || OM->hasAttr<ObjCReturnsInnerPointerAttr>()) return; - - QualType RT = OM->getResultType(); + + QualType RT = OM->getReturnType(); if (!TypeIsInnerPointer(RT) || !Ctx.Idents.get("NS_RETURNS_INNER_POINTER").hasMacroDefinition()) return; @@ -1153,14 +1156,11 @@ void ObjCMigrateASTConsumer::migratePropertyNsReturnsInnerPointer(ASTContext &Ct void ObjCMigrateASTConsumer::migrateAllMethodInstaceType(ASTContext &Ctx, ObjCContainerDecl *CDecl) { - if (CDecl->isDeprecated()) + if (CDecl->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(CDecl)) return; // migrate methods which can have instancetype as their result type. - for (ObjCContainerDecl::method_iterator M = CDecl->meth_begin(), - MEnd = CDecl->meth_end(); - M != MEnd; ++M) { - ObjCMethodDecl *Method = (*M); + for (auto *Method : CDecl->methods()) { if (Method->isDeprecated()) continue; migrateMethodInstanceType(Ctx, CDecl, Method); @@ -1172,8 +1172,8 @@ void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx, ObjCMethodDecl *OM, ObjCInstanceTypeFamily OIT_Family) { if (OM->isInstanceMethod() || - OM->getResultType() == Ctx.getObjCInstanceType() || - !OM->getResultType()->isObjCIdType()) + OM->getReturnType() == Ctx.getObjCInstanceType() || + !OM->getReturnType()->isObjCIdType()) return; // Candidate factory methods are + (id) NaMeXXX : ... which belong to a class @@ -1228,7 +1228,7 @@ void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx, if (OIT_Family == OIT_ReturnsSelf) ReplaceWithClasstype(*this, OM); else - ReplaceWithInstancetype(*this, OM); + ReplaceWithInstancetype(Ctx, *this, OM); } static bool IsVoidStarType(QualType Ty) { @@ -1338,7 +1338,7 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, // Annotate function. if (!ResultAnnotated) { RetEffect Ret = CE.getReturnValue(); - const char *AnnotationString = 0; + const char *AnnotationString = nullptr; if (Ret.getObjKind() == RetEffect::CF) { if (Ret.isOwned() && Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition()) @@ -1359,19 +1359,19 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, Editor->commit(commit); } } - llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs(); + ArrayRef<ArgEffect> AEArgs = CE.getArgs(); unsigned i = 0; for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(), pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) { const ParmVarDecl *pd = *pi; ArgEffect AE = AEArgs[i]; - if (AE == DecRef && !pd->getAttr<CFConsumedAttr>() && + if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() && Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) { edit::Commit commit(*Editor); commit.insertBefore(pd->getLocation(), "CF_CONSUMED "); Editor->commit(commit); } - else if (AE == DecRefMsg && !pd->getAttr<NSConsumedAttr>() && + else if (AE == DecRefMsg && !pd->hasAttr<NSConsumedAttr>() && Ctx.Idents.get("NS_CONSUMED").hasMacroDefinition()) { edit::Commit commit(*Editor); commit.insertBefore(pd->getLocation(), "NS_CONSUMED "); @@ -1389,11 +1389,11 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND return CF_BRIDGING_NONE; CallEffects CE = CallEffects::getEffect(FuncDecl); - bool FuncIsReturnAnnotated = (FuncDecl->getAttr<CFReturnsRetainedAttr>() || - FuncDecl->getAttr<CFReturnsNotRetainedAttr>() || - FuncDecl->getAttr<NSReturnsRetainedAttr>() || - FuncDecl->getAttr<NSReturnsNotRetainedAttr>() || - FuncDecl->getAttr<NSReturnsAutoreleasedAttr>()); + bool FuncIsReturnAnnotated = (FuncDecl->hasAttr<CFReturnsRetainedAttr>() || + FuncDecl->hasAttr<CFReturnsNotRetainedAttr>() || + FuncDecl->hasAttr<NSReturnsRetainedAttr>() || + FuncDecl->hasAttr<NSReturnsNotRetainedAttr>() || + FuncDecl->hasAttr<NSReturnsAutoreleasedAttr>()); // Trivial case of when funciton is annotated and has no argument. if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0) @@ -1405,13 +1405,13 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND if (Ret.getObjKind() == RetEffect::CF && (Ret.isOwned() || Ret.notOwned())) ReturnCFAudited = true; - else if (!AuditedType(FuncDecl->getResultType())) + else if (!AuditedType(FuncDecl->getReturnType())) return CF_BRIDGING_NONE; } // At this point result type is audited for potential inclusion. // Now, how about argument types. - llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs(); + ArrayRef<ArgEffect> AEArgs = CE.getArgs(); unsigned i = 0; bool ArgCFAudited = false; for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(), @@ -1419,7 +1419,7 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND const ParmVarDecl *pd = *pi; ArgEffect AE = AEArgs[i]; if (AE == DecRef /*CFConsumed annotated*/ || AE == IncRef) { - if (AE == DecRef && !pd->getAttr<CFConsumedAttr>()) + if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>()) ArgCFAudited = true; else if (AE == IncRef) ArgCFAudited = true; @@ -1444,12 +1444,8 @@ void ObjCMigrateASTConsumer::migrateARCSafeAnnotation(ASTContext &Ctx, return; // migrate methods which can have instancetype as their result type. - for (ObjCContainerDecl::method_iterator M = CDecl->meth_begin(), - MEnd = CDecl->meth_end(); - M != MEnd; ++M) { - ObjCMethodDecl *Method = (*M); + for (const auto *Method : CDecl->methods()) migrateCFAnnotation(Ctx, Method); - } } void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, @@ -1459,7 +1455,7 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, // Annotate function. if (!ResultAnnotated) { RetEffect Ret = CE.getReturnValue(); - const char *AnnotationString = 0; + const char *AnnotationString = nullptr; if (Ret.getObjKind() == RetEffect::CF) { if (Ret.isOwned() && Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition()) @@ -1492,13 +1488,13 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, Editor->commit(commit); } } - llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs(); + ArrayRef<ArgEffect> AEArgs = CE.getArgs(); unsigned i = 0; for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(), pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) { const ParmVarDecl *pd = *pi; ArgEffect AE = AEArgs[i]; - if (AE == DecRef && !pd->getAttr<CFConsumedAttr>() && + if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() && Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) { edit::Commit commit(*Editor); commit.insertBefore(pd->getLocation(), "CF_CONSUMED "); @@ -1514,14 +1510,14 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation( return; CallEffects CE = CallEffects::getEffect(MethodDecl); - bool MethodIsReturnAnnotated = (MethodDecl->getAttr<CFReturnsRetainedAttr>() || - MethodDecl->getAttr<CFReturnsNotRetainedAttr>() || - MethodDecl->getAttr<NSReturnsRetainedAttr>() || - MethodDecl->getAttr<NSReturnsNotRetainedAttr>() || - MethodDecl->getAttr<NSReturnsAutoreleasedAttr>()); + bool MethodIsReturnAnnotated = (MethodDecl->hasAttr<CFReturnsRetainedAttr>() || + MethodDecl->hasAttr<CFReturnsNotRetainedAttr>() || + MethodDecl->hasAttr<NSReturnsRetainedAttr>() || + MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() || + MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>()); if (CE.getReceiver() == DecRefMsg && - !MethodDecl->getAttr<NSConsumesSelfAttr>() && + !MethodDecl->hasAttr<NSConsumesSelfAttr>() && MethodDecl->getMethodFamily() != OMF_init && MethodDecl->getMethodFamily() != OMF_release && Ctx.Idents.get("NS_CONSUMES_SELF").hasMacroDefinition()) { @@ -1542,20 +1538,19 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation( (Ret.isOwned() || Ret.notOwned())) { AddCFAnnotations(Ctx, CE, MethodDecl, false); return; - } - else if (!AuditedType(MethodDecl->getResultType())) + } else if (!AuditedType(MethodDecl->getReturnType())) return; } // At this point result type is either annotated or audited. // Now, how about argument types. - llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs(); + ArrayRef<ArgEffect> AEArgs = CE.getArgs(); unsigned i = 0; for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(), pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) { const ParmVarDecl *pd = *pi; ArgEffect AE = AEArgs[i]; - if ((AE == DecRef && !pd->getAttr<CFConsumedAttr>()) || AE == IncRef || + if ((AE == DecRef && !pd->hasAttr<CFConsumedAttr>()) || AE == IncRef || !AuditedType(pd->getType())) { AddCFAnnotations(Ctx, CE, MethodDecl, MethodIsReturnAnnotated); return; @@ -1565,6 +1560,53 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation( } namespace { +class SuperInitChecker : public RecursiveASTVisitor<SuperInitChecker> { +public: + bool shouldVisitTemplateInstantiations() const { return false; } + bool shouldWalkTypesOfTypeLocs() const { return false; } + + bool VisitObjCMessageExpr(ObjCMessageExpr *E) { + if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance) { + if (E->getMethodFamily() == OMF_init) + return false; + } + return true; + } +}; +} // anonymous namespace + +static bool hasSuperInitCall(const ObjCMethodDecl *MD) { + return !SuperInitChecker().TraverseStmt(MD->getBody()); +} + +void ObjCMigrateASTConsumer::inferDesignatedInitializers( + ASTContext &Ctx, + const ObjCImplementationDecl *ImplD) { + + const ObjCInterfaceDecl *IFace = ImplD->getClassInterface(); + if (!IFace || IFace->hasDesignatedInitializers()) + return; + if (!Ctx.Idents.get("NS_DESIGNATED_INITIALIZER").hasMacroDefinition()) + return; + + for (const auto *MD : ImplD->instance_methods()) { + if (MD->isDeprecated() || + MD->getMethodFamily() != OMF_init || + MD->isDesignatedInitializerForTheInterface()) + continue; + const ObjCMethodDecl *IFaceM = IFace->getMethod(MD->getSelector(), + /*isInstance=*/true); + if (!IFaceM) + continue; + if (hasSuperInitCall(MD)) { + edit::Commit commit(*Editor); + commit.insert(IFaceM->getLocEnd(), " NS_DESIGNATED_INITIALIZER"); + Editor->commit(commit); + } + } +} + +namespace { class RewritesReceiver : public edit::EditsReceiver { Rewriter &Rewrite; @@ -1572,42 +1614,92 @@ class RewritesReceiver : public edit::EditsReceiver { public: RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { } - virtual void insert(SourceLocation loc, StringRef text) { + void insert(SourceLocation loc, StringRef text) override { Rewrite.InsertText(loc, text); } - virtual void replace(CharSourceRange range, StringRef text) { + void replace(CharSourceRange range, StringRef text) override { Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text); } }; -} +class JSONEditWriter : public edit::EditsReceiver { + SourceManager &SourceMgr; + llvm::raw_ostream &OS; -static bool -IsReallyASystemHeader(ASTContext &Ctx, const FileEntry *file, FileID FID) { - bool Invalid = false; - const SrcMgr::SLocEntry &SEntry = - Ctx.getSourceManager().getSLocEntry(FID, &Invalid); - if (!Invalid && SEntry.isFile()) { - const SrcMgr::FileInfo &FI = SEntry.getFile(); - if (!FI.hasLineDirectives()) { - if (FI.getFileCharacteristic() == SrcMgr::C_ExternCSystem) - return true; - if (FI.getFileCharacteristic() == SrcMgr::C_System) { - // This file is in a system header directory. Continue with commiting change - // only if it is a user specified system directory because user put a - // .system_framework file in the framework directory. - StringRef Directory(file->getDir()->getName()); - size_t Ix = Directory.rfind(".framework"); - if (Ix == StringRef::npos) - return true; - std::string PatchToSystemFramework = Directory.slice(0, Ix+sizeof(".framework")); - PatchToSystemFramework += ".system_framework"; - if (!llvm::sys::fs::exists(PatchToSystemFramework.data())) - return true; - } +public: + JSONEditWriter(SourceManager &SM, llvm::raw_ostream &OS) + : SourceMgr(SM), OS(OS) { + OS << "[\n"; + } + ~JSONEditWriter() { + OS << "]\n"; + } + +private: + struct EntryWriter { + SourceManager &SourceMgr; + llvm::raw_ostream &OS; + + EntryWriter(SourceManager &SM, llvm::raw_ostream &OS) + : SourceMgr(SM), OS(OS) { + OS << " {\n"; + } + ~EntryWriter() { + OS << " },\n"; } + + void writeLoc(SourceLocation Loc) { + FileID FID; + unsigned Offset; + std::tie(FID, Offset) = SourceMgr.getDecomposedLoc(Loc); + assert(!FID.isInvalid()); + SmallString<200> Path = + StringRef(SourceMgr.getFileEntryForID(FID)->getName()); + llvm::sys::fs::make_absolute(Path); + OS << " \"file\": \""; + OS.write_escaped(Path.str()) << "\",\n"; + OS << " \"offset\": " << Offset << ",\n"; + } + + void writeRemove(CharSourceRange Range) { + assert(Range.isCharRange()); + std::pair<FileID, unsigned> Begin = + SourceMgr.getDecomposedLoc(Range.getBegin()); + std::pair<FileID, unsigned> End = + SourceMgr.getDecomposedLoc(Range.getEnd()); + assert(Begin.first == End.first); + assert(Begin.second <= End.second); + unsigned Length = End.second - Begin.second; + + OS << " \"remove\": " << Length << ",\n"; + } + + void writeText(StringRef Text) { + OS << " \"text\": \""; + OS.write_escaped(Text) << "\",\n"; + } + }; + + void insert(SourceLocation Loc, StringRef Text) override { + EntryWriter Writer(SourceMgr, OS); + Writer.writeLoc(Loc); + Writer.writeText(Text); } - return false; + + void replace(CharSourceRange Range, StringRef Text) override { + EntryWriter Writer(SourceMgr, OS); + Writer.writeLoc(Range.getBegin()); + Writer.writeRemove(Range); + Writer.writeText(Text); + } + + void remove(CharSourceRange Range) override { + EntryWriter Writer(SourceMgr, OS); + Writer.writeLoc(Range.getBegin()); + Writer.writeRemove(Range); + } +}; + } void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { @@ -1624,22 +1716,25 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { } if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D)) - migrateObjCInterfaceDecl(Ctx, CDecl); + if (canModify(CDecl)) + migrateObjCInterfaceDecl(Ctx, CDecl); if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(*D)) { - migrateObjCInterfaceDecl(Ctx, CatDecl); - if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) - migrateDeprecatedAnnotation(Ctx, CatDecl); + if (canModify(CatDecl)) + migrateObjCInterfaceDecl(Ctx, CatDecl); } else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(*D)) - ObjCProtocolDecls.insert(PDecl); + ObjCProtocolDecls.insert(PDecl->getCanonicalDecl()); else if (const ObjCImplementationDecl *ImpDecl = dyn_cast<ObjCImplementationDecl>(*D)) { - if (ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance) + if ((ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance) && + canModify(ImpDecl)) migrateProtocolConformance(Ctx, ImpDecl); } else if (const EnumDecl *ED = dyn_cast<EnumDecl>(*D)) { if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros)) continue; + if (!canModify(ED)) + continue; DeclContext::decl_iterator N = D; if (++N != DEnd) { const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N); @@ -1647,11 +1742,13 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { D++; } else - migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */0); + migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */nullptr); } else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*D)) { if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros)) continue; + if (!canModify(TD)) + continue; DeclContext::decl_iterator N = D; if (++N == DEnd) continue; @@ -1673,23 +1770,49 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { CacheObjCNSIntegerTypedefed(TD); } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*D)) { - if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) + if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) && + canModify(FD)) migrateCFAnnotation(Ctx, FD); } if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(*D)) { + bool CanModify = canModify(CDecl); // migrate methods which can have instancetype as their result type. - if (ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype) + if ((ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype) && + CanModify) migrateAllMethodInstaceType(Ctx, CDecl); // annotate methods with CF annotations. - if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) + if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) && + CanModify) migrateARCSafeAnnotation(Ctx, CDecl); } + + if (const ObjCImplementationDecl * + ImplD = dyn_cast<ObjCImplementationDecl>(*D)) { + if ((ASTMigrateActions & FrontendOptions::ObjCMT_DesignatedInitializer) && + canModify(ImplD)) + inferDesignatedInitializers(Ctx, ImplD); + } } if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) AnnotateImplicitBridging(Ctx); } + if (IsOutputFile) { + std::string Error; + llvm::raw_fd_ostream OS(MigrateDir.c_str(), Error, llvm::sys::fs::F_None); + if (!Error.empty()) { + DiagnosticsEngine &Diags = Ctx.getDiagnostics(); + Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0")) + << Error; + return; + } + + JSONEditWriter Writer(Ctx.getSourceManager(), OS); + Editor->applyRewrites(Writer); + return; + } + Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); RewritesReceiver Rec(rewriter); Editor->applyRewrites(Rec); @@ -1700,10 +1823,6 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { RewriteBuffer &buf = I->second; const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID); assert(file); - if (IsReallyASystemHeader(Ctx, file, FID)) - continue; - if (!canModifyFile(file->getName())) - continue; SmallString<512> newText; llvm::raw_svector_ostream vecOS(newText); buf.write(vecOS); @@ -1734,8 +1853,8 @@ static std::vector<std::string> getWhiteListFilenames(StringRef DirPath) { std::vector<std::string> Filenames; if (DirPath.empty() || !is_directory(DirPath)) return Filenames; - - llvm::error_code EC; + + std::error_code EC; directory_iterator DI = directory_iterator(DirPath, EC); directory_iterator DE; for (; !EC && DI != DE; DI = DI.increment(EC)) { @@ -1773,3 +1892,246 @@ ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, /*isOutputFile=*/true, WhiteList); } + +namespace { +struct EditEntry { + const FileEntry *File; + unsigned Offset; + unsigned RemoveLen; + std::string Text; + + EditEntry() : File(), Offset(), RemoveLen() {} +}; +} + +namespace llvm { +template<> struct DenseMapInfo<EditEntry> { + static inline EditEntry getEmptyKey() { + EditEntry Entry; + Entry.Offset = unsigned(-1); + return Entry; + } + static inline EditEntry getTombstoneKey() { + EditEntry Entry; + Entry.Offset = unsigned(-2); + return Entry; + } + static unsigned getHashValue(const EditEntry& Val) { + llvm::FoldingSetNodeID ID; + ID.AddPointer(Val.File); + ID.AddInteger(Val.Offset); + ID.AddInteger(Val.RemoveLen); + ID.AddString(Val.Text); + return ID.ComputeHash(); + } + static bool isEqual(const EditEntry &LHS, const EditEntry &RHS) { + return LHS.File == RHS.File && + LHS.Offset == RHS.Offset && + LHS.RemoveLen == RHS.RemoveLen && + LHS.Text == RHS.Text; + } +}; +} + +namespace { +class RemapFileParser { + FileManager &FileMgr; + +public: + RemapFileParser(FileManager &FileMgr) : FileMgr(FileMgr) { } + + bool parse(StringRef File, SmallVectorImpl<EditEntry> &Entries) { + using namespace llvm::yaml; + + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr = + llvm::MemoryBuffer::getFile(File); + if (!FileBufOrErr) + return true; + + llvm::SourceMgr SM; + Stream YAMLStream(FileBufOrErr.get().release(), SM); + document_iterator I = YAMLStream.begin(); + if (I == YAMLStream.end()) + return true; + Node *Root = I->getRoot(); + if (!Root) + return true; + + SequenceNode *SeqNode = dyn_cast<SequenceNode>(Root); + if (!SeqNode) + return true; + + for (SequenceNode::iterator + AI = SeqNode->begin(), AE = SeqNode->end(); AI != AE; ++AI) { + MappingNode *MapNode = dyn_cast<MappingNode>(&*AI); + if (!MapNode) + continue; + parseEdit(MapNode, Entries); + } + + return false; + } + +private: + void parseEdit(llvm::yaml::MappingNode *Node, + SmallVectorImpl<EditEntry> &Entries) { + using namespace llvm::yaml; + EditEntry Entry; + bool Ignore = false; + + for (MappingNode::iterator + KVI = Node->begin(), KVE = Node->end(); KVI != KVE; ++KVI) { + ScalarNode *KeyString = dyn_cast<ScalarNode>((*KVI).getKey()); + if (!KeyString) + continue; + SmallString<10> KeyStorage; + StringRef Key = KeyString->getValue(KeyStorage); + + ScalarNode *ValueString = dyn_cast<ScalarNode>((*KVI).getValue()); + if (!ValueString) + continue; + SmallString<64> ValueStorage; + StringRef Val = ValueString->getValue(ValueStorage); + + if (Key == "file") { + const FileEntry *FE = FileMgr.getFile(Val); + if (!FE) + Ignore = true; + Entry.File = FE; + } else if (Key == "offset") { + if (Val.getAsInteger(10, Entry.Offset)) + Ignore = true; + } else if (Key == "remove") { + if (Val.getAsInteger(10, Entry.RemoveLen)) + Ignore = true; + } else if (Key == "text") { + Entry.Text = Val; + } + } + + if (!Ignore) + Entries.push_back(Entry); + } +}; +} + +static bool reportDiag(const Twine &Err, DiagnosticsEngine &Diag) { + Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0")) + << Err.str(); + return true; +} + +static std::string applyEditsToTemp(const FileEntry *FE, + ArrayRef<EditEntry> Edits, + FileManager &FileMgr, + DiagnosticsEngine &Diag) { + using namespace llvm::sys; + + SourceManager SM(Diag, FileMgr); + FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User); + LangOptions LangOpts; + edit::EditedSource Editor(SM, LangOpts); + for (ArrayRef<EditEntry>::iterator + I = Edits.begin(), E = Edits.end(); I != E; ++I) { + const EditEntry &Entry = *I; + assert(Entry.File == FE); + SourceLocation Loc = + SM.getLocForStartOfFile(FID).getLocWithOffset(Entry.Offset); + CharSourceRange Range; + if (Entry.RemoveLen != 0) { + Range = CharSourceRange::getCharRange(Loc, + Loc.getLocWithOffset(Entry.RemoveLen)); + } + + edit::Commit commit(Editor); + if (Range.isInvalid()) { + commit.insert(Loc, Entry.Text); + } else if (Entry.Text.empty()) { + commit.remove(Range); + } else { + commit.replace(Range, Entry.Text); + } + Editor.commit(commit); + } + + Rewriter rewriter(SM, LangOpts); + RewritesReceiver Rec(rewriter); + Editor.applyRewrites(Rec); + + const RewriteBuffer *Buf = rewriter.getRewriteBufferFor(FID); + SmallString<512> NewText; + llvm::raw_svector_ostream OS(NewText); + Buf->write(OS); + OS.flush(); + + SmallString<64> TempPath; + int FD; + if (fs::createTemporaryFile(path::filename(FE->getName()), + path::extension(FE->getName()), FD, + TempPath)) { + reportDiag("Could not create file: " + TempPath.str(), Diag); + return std::string(); + } + + llvm::raw_fd_ostream TmpOut(FD, /*shouldClose=*/true); + TmpOut.write(NewText.data(), NewText.size()); + TmpOut.close(); + + return TempPath.str(); +} + +bool arcmt::getFileRemappingsFromFileList( + std::vector<std::pair<std::string,std::string> > &remap, + ArrayRef<StringRef> remapFiles, + DiagnosticConsumer *DiagClient) { + bool hasErrorOccurred = false; + + FileSystemOptions FSOpts; + FileManager FileMgr(FSOpts); + RemapFileParser Parser(FileMgr); + + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags( + new DiagnosticsEngine(DiagID, new DiagnosticOptions, + DiagClient, /*ShouldOwnClient=*/false)); + + typedef llvm::DenseMap<const FileEntry *, std::vector<EditEntry> > + FileEditEntriesTy; + FileEditEntriesTy FileEditEntries; + + llvm::DenseSet<EditEntry> EntriesSet; + + for (ArrayRef<StringRef>::iterator + I = remapFiles.begin(), E = remapFiles.end(); I != E; ++I) { + SmallVector<EditEntry, 16> Entries; + if (Parser.parse(*I, Entries)) + continue; + + for (SmallVectorImpl<EditEntry>::iterator + EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) { + EditEntry &Entry = *EI; + if (!Entry.File) + continue; + std::pair<llvm::DenseSet<EditEntry>::iterator, bool> + Insert = EntriesSet.insert(Entry); + if (!Insert.second) + continue; + + FileEditEntries[Entry.File].push_back(Entry); + } + } + + for (FileEditEntriesTy::iterator + I = FileEditEntries.begin(), E = FileEditEntries.end(); I != E; ++I) { + std::string TempFile = applyEditsToTemp(I->first, I->second, + FileMgr, *Diags); + if (TempFile.empty()) { + hasErrorOccurred = true; + continue; + } + + remap.push_back(std::make_pair(I->first->getName(), TempFile)); + } + + return hasErrorOccurred; +} diff --git a/lib/ARCMigrate/PlistReporter.cpp b/lib/ARCMigrate/PlistReporter.cpp index 144ba2e398ad..6b34ef0c2b9e 100644 --- a/lib/ARCMigrate/PlistReporter.cpp +++ b/lib/ARCMigrate/PlistReporter.cpp @@ -9,86 +9,27 @@ #include "Internals.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/PlistSupport.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" using namespace clang; using namespace arcmt; - -// FIXME: This duplicates significant functionality from PlistDiagnostics.cpp, -// it would be jolly good if there was a reusable PlistWriter or something. - -typedef llvm::DenseMap<FileID, unsigned> FIDMap; - -static void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V, - const SourceManager &SM, SourceLocation L) { - - FileID FID = SM.getFileID(SM.getExpansionLoc(L)); - FIDMap::iterator I = FIDs.find(FID); - if (I != FIDs.end()) return; - FIDs[FID] = V.size(); - V.push_back(FID); -} - -static unsigned GetFID(const FIDMap& FIDs, const SourceManager &SM, - SourceLocation L) { - FileID FID = SM.getFileID(SM.getExpansionLoc(L)); - FIDMap::const_iterator I = FIDs.find(FID); - assert(I != FIDs.end()); - return I->second; -} - -static raw_ostream& Indent(raw_ostream& o, const unsigned indent) { - for (unsigned i = 0; i < indent; ++i) o << ' '; - return o; -} - -static void EmitLocation(raw_ostream& o, const SourceManager &SM, - const LangOptions &LangOpts, - SourceLocation L, const FIDMap &FM, - unsigned indent, bool extend = false) { - - FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager&>(SM)); - - // Add in the length of the token, so that we cover multi-char tokens. - unsigned offset = - extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0; - - Indent(o, indent) << "<dict>\n"; - Indent(o, indent) << " <key>line</key><integer>" - << Loc.getExpansionLineNumber() << "</integer>\n"; - Indent(o, indent) << " <key>col</key><integer>" - << Loc.getExpansionColumnNumber() + offset << "</integer>\n"; - Indent(o, indent) << " <key>file</key><integer>" - << GetFID(FM, SM, Loc) << "</integer>\n"; - Indent(o, indent) << "</dict>\n"; -} - -static void EmitRange(raw_ostream& o, const SourceManager &SM, - const LangOptions &LangOpts, - CharSourceRange R, const FIDMap &FM, - unsigned indent) { - Indent(o, indent) << "<array>\n"; - EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent+1); - EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent+1, R.isTokenRange()); - Indent(o, indent) << "</array>\n"; -} - -static raw_ostream& EmitString(raw_ostream& o, - StringRef s) { - o << "<string>"; - for (StringRef::const_iterator I=s.begin(), E=s.end(); I!=E; ++I) { - char c = *I; - switch (c) { - default: o << c; break; - case '&': o << "&"; break; - case '<': o << "<"; break; - case '>': o << ">"; break; - case '\'': o << "'"; break; - case '\"': o << """; break; - } +using namespace markup; + +static StringRef getLevelName(DiagnosticsEngine::Level Level) { + switch (Level) { + case DiagnosticsEngine::Ignored: + llvm_unreachable("ignored"); + case DiagnosticsEngine::Note: + return "note"; + case DiagnosticsEngine::Remark: + case DiagnosticsEngine::Warning: + return "warning"; + case DiagnosticsEngine::Fatal: + case DiagnosticsEngine::Error: + return "error"; } - o << "</string>"; - return o; + llvm_unreachable("Invalid DiagnosticsEngine level!"); } void arcmt::writeARCDiagsToPlist(const std::string &outPath, @@ -116,17 +57,13 @@ void arcmt::writeARCDiagsToPlist(const std::string &outPath, } std::string errMsg; - llvm::raw_fd_ostream o(outPath.c_str(), errMsg); + llvm::raw_fd_ostream o(outPath.c_str(), errMsg, llvm::sys::fs::F_Text); if (!errMsg.empty()) { llvm::errs() << "error: could not create file: " << outPath << '\n'; return; } - // Write the plist header. - o << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" " - "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" - "<plist version=\"1.0\">\n"; + EmitPlistHeader(o); // Write the root object: a <dict> containing... // - "files", an <array> mapping from FIDs to file names @@ -135,11 +72,8 @@ void arcmt::writeARCDiagsToPlist(const std::string &outPath, " <key>files</key>\n" " <array>\n"; - for (SmallVectorImpl<FileID>::iterator I=Fids.begin(), E=Fids.end(); - I!=E; ++I) { - o << " "; - EmitString(o, SM.getFileEntryForID(*I)->getName()) << '\n'; - } + for (FileID FID : Fids) + EmitString(o << " ", SM.getFileEntryForID(FID)->getName()) << '\n'; o << " </array>\n" " <key>diagnostics</key>\n" @@ -162,12 +96,7 @@ void arcmt::writeARCDiagsToPlist(const std::string &outPath, EmitString(o, DiagIDs.getCategoryNameFromID( DiagIDs.getCategoryNumberForDiag(D.getID()))) << '\n'; o << " <key>type</key>"; - if (D.getLevel() >= DiagnosticsEngine::Error) - EmitString(o, "error") << '\n'; - else if (D.getLevel() == DiagnosticsEngine::Warning) - EmitString(o, "warning") << '\n'; - else - EmitString(o, "note") << '\n'; + EmitString(o, getLevelName(D.getLevel())) << '\n'; // Output the location of the bug. o << " <key>location</key>\n"; diff --git a/lib/ARCMigrate/TransAPIUses.cpp b/lib/ARCMigrate/TransAPIUses.cpp index a0994a6b459a..544cb0addfcd 100644 --- a/lib/ARCMigrate/TransAPIUses.cpp +++ b/lib/ARCMigrate/TransAPIUses.cpp @@ -66,8 +66,7 @@ public: selName = "getArgument"; else if (E->getSelector() == setArgumentSel) selName = "setArgument"; - - if (selName.empty()) + else return true; Expr *parm = E->getArg(0)->IgnoreParenCasts(); @@ -75,13 +74,12 @@ public: if (pointee.isNull()) return true; - if (pointee.getObjCLifetime() > Qualifiers::OCL_ExplicitNone) { - std::string err = "NSInvocation's "; - err += selName; - err += " is not safe to be used with an object with ownership other " - "than __unsafe_unretained"; - Pass.TA.reportError(err, parm->getLocStart(), parm->getSourceRange()); - } + if (pointee.getObjCLifetime() > Qualifiers::OCL_ExplicitNone) + Pass.TA.report(parm->getLocStart(), + diag::err_arcmt_nsinvocation_ownership, + parm->getSourceRange()) + << selName; + return true; } diff --git a/lib/ARCMigrate/TransAutoreleasePool.cpp b/lib/ARCMigrate/TransAutoreleasePool.cpp index a2990e7226ab..a8a99fa712a3 100644 --- a/lib/ARCMigrate/TransAutoreleasePool.cpp +++ b/lib/ARCMigrate/TransAutoreleasePool.cpp @@ -70,7 +70,7 @@ class AutoreleasePoolRewriter : public RecursiveASTVisitor<AutoreleasePoolRewriter> { public: AutoreleasePoolRewriter(MigrationPass &pass) - : Body(0), Pass(pass) { + : Body(nullptr), Pass(pass) { PoolII = &pass.Ctx.Idents.get("NSAutoreleasePool"); DrainSel = pass.Ctx.Selectors.getNullarySelector( &pass.Ctx.Idents.get("drain")); @@ -230,7 +230,7 @@ private: bool IsFollowedBySimpleReturnStmt; SmallVector<ObjCMessageExpr *, 4> Releases; - PoolScope() : PoolVar(0), CompoundParent(0), Begin(), End(), + PoolScope() : PoolVar(nullptr), CompoundParent(nullptr), Begin(), End(), IsFollowedBySimpleReturnStmt(false) { } SourceRange getIndentedRange() const { @@ -305,7 +305,7 @@ private: // statement, in which case we will include the return in the scope. if (SI != SE) if (ReturnStmt *retS = dyn_cast<ReturnStmt>(*SI)) - if ((retS->getRetValue() == 0 || + if ((retS->getRetValue() == nullptr || isa<DeclRefExpr>(retS->getRetValue()->IgnoreParenCasts())) && findLocationAfterSemi(retS->getLocEnd(), Pass.Ctx).isValid()) { scope.IsFollowedBySimpleReturnStmt = true; @@ -421,7 +421,7 @@ private: ExprSet Refs; SmallVector<PoolScope, 2> Scopes; - PoolVarInfo() : Dcl(0) { } + PoolVarInfo() : Dcl(nullptr) { } }; std::map<VarDecl *, PoolVarInfo> PoolVars; diff --git a/lib/ARCMigrate/TransBlockObjCVariable.cpp b/lib/ARCMigrate/TransBlockObjCVariable.cpp index 97c4e3480c15..fac6a84c45e5 100644 --- a/lib/ARCMigrate/TransBlockObjCVariable.cpp +++ b/lib/ARCMigrate/TransBlockObjCVariable.cpp @@ -78,10 +78,9 @@ public: bool VisitBlockDecl(BlockDecl *block) { SmallVector<VarDecl *, 4> BlockVars; - for (BlockDecl::capture_iterator - I = block->capture_begin(), E = block->capture_end(); I != E; ++I) { - VarDecl *var = I->getVariable(); - if (I->isByRef() && + for (const auto &I : block->captures()) { + VarDecl *var = I.getVariable(); + if (I.isByRef() && var->getType()->isObjCObjectPointerType() && isImplicitStrong(var->getType())) { BlockVars.push_back(var); diff --git a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp index ffb638f8a306..9689f40760cd 100644 --- a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp +++ b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp @@ -89,9 +89,8 @@ public: bool VisitCompoundStmt(CompoundStmt *S) { if (S->body_empty()) return false; // was already empty, not because of transformations. - for (CompoundStmt::body_iterator - I = S->body_begin(), E = S->body_end(); I != E; ++I) - if (!Visit(*I)) + for (auto *I : S->body()) + if (!Visit(I)) return false; return true; } @@ -167,9 +166,8 @@ public: } bool VisitCompoundStmt(CompoundStmt *S) { - for (CompoundStmt::body_iterator - I = S->body_begin(), E = S->body_end(); I != E; ++I) - check(*I); + for (auto *I : S->body()) + check(I); return true; } @@ -189,9 +187,8 @@ private: static bool isBodyEmpty(CompoundStmt *body, ASTContext &Ctx, std::vector<SourceLocation> &MacroLocs) { - for (CompoundStmt::body_iterator - I = body->body_begin(), E = body->body_end(); I != E; ++I) - if (!EmptyChecker(Ctx, MacroLocs).Visit(*I)) + for (auto *I : body->body()) + if (!EmptyChecker(Ctx, MacroLocs).Visit(I)) return false; return true; @@ -208,12 +205,9 @@ static void cleanupDeallocOrFinalize(MigrationPass &pass) { impl_iterator; for (impl_iterator I = impl_iterator(DC->decls_begin()), E = impl_iterator(DC->decls_end()); I != E; ++I) { - ObjCMethodDecl *DeallocM = 0; - ObjCMethodDecl *FinalizeM = 0; - for (ObjCImplementationDecl::instmeth_iterator - MI = I->instmeth_begin(), - ME = I->instmeth_end(); MI != ME; ++MI) { - ObjCMethodDecl *MD = *MI; + ObjCMethodDecl *DeallocM = nullptr; + ObjCMethodDecl *FinalizeM = nullptr; + for (auto *MD : I->instance_methods()) { if (!MD->hasBody()) continue; diff --git a/lib/ARCMigrate/TransGCAttrs.cpp b/lib/ARCMigrate/TransGCAttrs.cpp index d8be1ae746ab..10fce19b6f19 100644 --- a/lib/ARCMigrate/TransGCAttrs.cpp +++ b/lib/ARCMigrate/TransGCAttrs.cpp @@ -80,7 +80,7 @@ public: } } - bool handleAttr(AttributedTypeLoc TL, Decl *D = 0) { + bool handleAttr(AttributedTypeLoc TL, Decl *D = nullptr) { if (TL.getAttrKind() != AttributedType::attr_objc_ownership) return false; @@ -134,8 +134,7 @@ public: return hasObjCImpl(ContD); if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { - for (CXXRecordDecl::method_iterator - MI = RD->method_begin(), ME = RD->method_end(); MI != ME; ++MI) { + for (const auto *MI : RD->methods()) { if (MI->isOutOfLine()) return true; } @@ -150,9 +149,9 @@ public: return false; if (ObjCContainerDecl *ContD = dyn_cast<ObjCContainerDecl>(D)) { if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(ContD)) - return ID->getImplementation() != 0; + return ID->getImplementation() != nullptr; if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContD)) - return CD->getImplementation() != 0; + return CD->getImplementation() != nullptr; if (isa<ObjCImplDecl>(ContD)) return true; return false; @@ -164,8 +163,7 @@ public: if (!D) return false; - for (Decl::redecl_iterator - I = D->redecls_begin(), E = D->redecls_end(); I != E; ++I) + for (auto I : D->redecls()) if (!isInMainFile(I->getLocation())) return false; diff --git a/lib/ARCMigrate/TransGCCalls.cpp b/lib/ARCMigrate/TransGCCalls.cpp index 249f20f01b22..3a236d34cd4b 100644 --- a/lib/ARCMigrate/TransGCCalls.cpp +++ b/lib/ARCMigrate/TransGCCalls.cpp @@ -38,14 +38,8 @@ public: TransformActions &TA = MigrateCtx.Pass.TA; if (MigrateCtx.isGCOwnedNonObjC(E->getType())) { - if (MigrateCtx.Pass.noNSAllocReallocError()) - TA.reportWarning("call returns pointer to GC managed memory; " - "it will become unmanaged in ARC", - E->getLocStart(), E->getSourceRange()); - else - TA.reportError("call returns pointer to GC managed memory; " - "it will become unmanaged in ARC", - E->getLocStart(), E->getSourceRange()); + TA.report(E->getLocStart(), diag::warn_arcmt_nsalloc_realloc, + E->getSourceRange()); return true; } diff --git a/lib/ARCMigrate/TransProperties.cpp b/lib/ARCMigrate/TransProperties.cpp index b6ddc43dd69f..ab128844b45f 100644 --- a/lib/ARCMigrate/TransProperties.cpp +++ b/lib/ARCMigrate/TransProperties.cpp @@ -61,7 +61,8 @@ class PropertiesRewriter { ObjCIvarDecl *IvarD; ObjCPropertyImplDecl *ImplD; - PropData(ObjCPropertyDecl *propD) : PropD(propD), IvarD(0), ImplD(0) { } + PropData(ObjCPropertyDecl *propD) + : PropD(propD), IvarD(nullptr), ImplD(nullptr) {} }; typedef SmallVector<PropData, 2> PropsTy; @@ -74,18 +75,16 @@ public: : MigrateCtx(MigrateCtx), Pass(MigrateCtx.Pass) { } static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps, - AtPropDeclsTy *PrevAtProps = 0) { - for (ObjCInterfaceDecl::prop_iterator - propI = D->prop_begin(), - propE = D->prop_end(); propI != propE; ++propI) { - if (propI->getAtLoc().isInvalid()) + AtPropDeclsTy *PrevAtProps = nullptr) { + for (auto *Prop : D->properties()) { + if (Prop->getAtLoc().isInvalid()) continue; - unsigned RawLoc = propI->getAtLoc().getRawEncoding(); + unsigned RawLoc = Prop->getAtLoc().getRawEncoding(); if (PrevAtProps) if (PrevAtProps->find(RawLoc) != PrevAtProps->end()) continue; PropsTy &props = AtProps[RawLoc]; - props.push_back(*propI); + props.push_back(Prop); } } @@ -141,12 +140,8 @@ public: AtPropDeclsTy AtExtProps; // Look through extensions. - for (ObjCInterfaceDecl::visible_extensions_iterator - ext = iface->visible_extensions_begin(), - extEnd = iface->visible_extensions_end(); - ext != extEnd; ++ext) { - collectProperties(*ext, AtExtProps, &AtProps); - } + for (auto *Ext : iface->visible_extensions()) + collectProperties(Ext, AtExtProps, &AtProps); for (AtPropDeclsTy::iterator I = AtExtProps.begin(), E = AtExtProps.end(); I != E; ++I) { @@ -353,14 +348,6 @@ private: return false; } - bool hasAllIvarsBacked(PropsTy &props) const { - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) - if (!isUserDeclared(I->IvarD)) - return false; - - return true; - } - // \brief Returns true if all declarations in the @property have GC __weak. bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const { if (!Pass.isGCMigration()) diff --git a/lib/ARCMigrate/TransProtectedScope.cpp b/lib/ARCMigrate/TransProtectedScope.cpp index 237aa42877e6..0fcbcbedfe04 100644 --- a/lib/ARCMigrate/TransProtectedScope.cpp +++ b/lib/ARCMigrate/TransProtectedScope.cpp @@ -47,7 +47,7 @@ struct CaseInfo { St_Fixed } State; - CaseInfo() : SC(0), State(St_Unchecked) {} + CaseInfo() : SC(nullptr), State(St_Unchecked) {} CaseInfo(SwitchCase *S, SourceRange Range) : SC(S), Range(Range), State(St_Unchecked) {} }; diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp index 446a284a286f..bcbc9e9612ba 100644 --- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp +++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp @@ -38,13 +38,13 @@ class RetainReleaseDeallocRemover : MigrationPass &Pass; ExprSet Removables; - OwningPtr<ParentMap> StmtMap; + std::unique_ptr<ParentMap> StmtMap; Selector DelegateSel, FinalizeSel; public: RetainReleaseDeallocRemover(MigrationPass &pass) - : Body(0), Pass(pass) { + : Body(nullptr), Pass(pass) { DelegateSel = Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("delegate")); FinalizeSel = @@ -70,7 +70,7 @@ public: // An unused autorelease is badness. If we remove it the receiver // will likely die immediately while previously it was kept alive // by the autorelease pool. This is bad practice in general, leave it - // and emit an error to force the user to restructure his code. + // and emit an error to force the user to restructure their code. Pass.TA.reportError("it is not safe to remove an unused 'autorelease' " "message; its receiver may be destroyed immediately", E->getLocStart(), E->getSourceRange()); @@ -212,7 +212,7 @@ private: return false; Stmt *prevStmt, *nextStmt; - llvm::tie(prevStmt, nextStmt) = getPreviousAndNextStmt(E); + std::tie(prevStmt, nextStmt) = getPreviousAndNextStmt(E); return isPlusOneAssignToVar(prevStmt, RefD) || isPlusOneAssignToVar(nextStmt, RefD); @@ -248,7 +248,7 @@ private: } std::pair<Stmt *, Stmt *> getPreviousAndNextStmt(Expr *E) { - Stmt *prevStmt = 0, *nextStmt = 0; + Stmt *prevStmt = nullptr, *nextStmt = nullptr; if (!E) return std::make_pair(prevStmt, nextStmt); @@ -294,7 +294,7 @@ private: Decl *getReferencedDecl(Expr *E) { if (!E) - return 0; + return nullptr; E = E->IgnoreParenCasts(); if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) { @@ -305,7 +305,7 @@ private: case OMF_retain: return getReferencedDecl(ME->getInstanceReceiver()); default: - return 0; + return nullptr; } } if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) @@ -315,7 +315,7 @@ private: if (ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(E)) return IRE->getDecl(); - return 0; + return nullptr; } /// \brief Check if the retain/release is due to a GCD/XPC macro that are @@ -345,7 +345,7 @@ private: if (!isGCDOrXPC) return; - StmtExpr *StmtE = 0; + StmtExpr *StmtE = nullptr; Stmt *S = Msg; while (S) { if (StmtExpr *SE = dyn_cast<StmtExpr>(S)) { diff --git a/lib/ARCMigrate/TransUnbridgedCasts.cpp b/lib/ARCMigrate/TransUnbridgedCasts.cpp index 7b360c640cfd..7ca49558a7f0 100644 --- a/lib/ARCMigrate/TransUnbridgedCasts.cpp +++ b/lib/ARCMigrate/TransUnbridgedCasts.cpp @@ -60,13 +60,14 @@ namespace { class UnbridgedCastRewriter : public RecursiveASTVisitor<UnbridgedCastRewriter>{ MigrationPass &Pass; IdentifierInfo *SelfII; - OwningPtr<ParentMap> StmtMap; + std::unique_ptr<ParentMap> StmtMap; Decl *ParentD; Stmt *Body; - mutable OwningPtr<ExprSet> Removables; + mutable std::unique_ptr<ExprSet> Removables; public: - UnbridgedCastRewriter(MigrationPass &pass) : Pass(pass), ParentD(0), Body(0) { + UnbridgedCastRewriter(MigrationPass &pass) + : Pass(pass), ParentD(nullptr), Body(nullptr) { SelfII = &Pass.Ctx.Idents.get("self"); } @@ -133,11 +134,11 @@ private: Expr *inner = E->IgnoreParenCasts(); if (CallExpr *callE = dyn_cast<CallExpr>(inner)) { if (FunctionDecl *FD = callE->getDirectCallee()) { - if (FD->getAttr<CFReturnsRetainedAttr>()) { + if (FD->hasAttr<CFReturnsRetainedAttr>()) { castToObjCObject(E, /*retained=*/true); return; } - if (FD->getAttr<CFReturnsNotRetainedAttr>()) { + if (FD->hasAttr<CFReturnsNotRetainedAttr>()) { castToObjCObject(E, /*retained=*/false); return; } @@ -283,7 +284,7 @@ private: SourceLocation Loc = E->getExprLoc(); assert(Loc.isMacroID()); SourceLocation MacroBegin, MacroEnd; - llvm::tie(MacroBegin, MacroEnd) = SM.getImmediateExpansionRange(Loc); + std::tie(MacroBegin, MacroEnd) = SM.getImmediateExpansionRange(Loc); SourceRange SubRange = E->getSubExpr()->IgnoreParenImpCasts()->getSourceRange(); SourceLocation InnerBegin = SM.getImmediateMacroCallerLoc(SubRange.getBegin()); SourceLocation InnerEnd = SM.getImmediateMacroCallerLoc(SubRange.getEnd()); @@ -439,7 +440,7 @@ private: } if (i < callE->getNumArgs() && i < FD->getNumParams()) { ParmVarDecl *PD = FD->getParamDecl(i); - if (PD->getAttr<CFConsumedAttr>()) { + if (PD->hasAttr<CFConsumedAttr>()) { isConsumed = true; return true; } diff --git a/lib/ARCMigrate/TransUnusedInitDelegate.cpp b/lib/ARCMigrate/TransUnusedInitDelegate.cpp index e316c73fc3cd..98571c035dd5 100644 --- a/lib/ARCMigrate/TransUnusedInitDelegate.cpp +++ b/lib/ARCMigrate/TransUnusedInitDelegate.cpp @@ -39,7 +39,7 @@ class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> { public: UnusedInitRewriter(MigrationPass &pass) - : Body(0), Pass(pass) { } + : Body(nullptr), Pass(pass) { } void transformBody(Stmt *body, Decl *ParentD) { Body = body; diff --git a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp index 4d088e05bfab..76ce0ec90db3 100644 --- a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp +++ b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp @@ -35,7 +35,7 @@ class ZeroOutInDeallocRemover : Selector FinalizeSel; public: - ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(0) { + ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(nullptr) { FinalizeSel = Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize")); } @@ -113,23 +113,21 @@ public: // For a 'dealloc' method use, find all property implementations in // this class implementation. - for (ObjCImplDecl::propimpl_iterator - I = IMD->propimpl_begin(), EI = IMD->propimpl_end(); I != EI; ++I) { - ObjCPropertyImplDecl *PID = *I; - if (PID->getPropertyImplementation() == - ObjCPropertyImplDecl::Synthesize) { - ObjCPropertyDecl *PD = PID->getPropertyDecl(); - ObjCMethodDecl *setterM = PD->getSetterMethodDecl(); - if (!(setterM && setterM->isDefined())) { - ObjCPropertyDecl::PropertyAttributeKind AttrKind = - PD->getPropertyAttributes(); - if (AttrKind & - (ObjCPropertyDecl::OBJC_PR_retain | - ObjCPropertyDecl::OBJC_PR_copy | - ObjCPropertyDecl::OBJC_PR_strong)) - SynthesizedProperties[PD] = PID; - } + for (auto *PID : IMD->property_impls()) { + if (PID->getPropertyImplementation() == + ObjCPropertyImplDecl::Synthesize) { + ObjCPropertyDecl *PD = PID->getPropertyDecl(); + ObjCMethodDecl *setterM = PD->getSetterMethodDecl(); + if (!(setterM && setterM->isDefined())) { + ObjCPropertyDecl::PropertyAttributeKind AttrKind = + PD->getPropertyAttributes(); + if (AttrKind & + (ObjCPropertyDecl::OBJC_PR_retain | + ObjCPropertyDecl::OBJC_PR_copy | + ObjCPropertyDecl::OBJC_PR_strong)) + SynthesizedProperties[PD] = PID; } + } } // Now, remove all zeroing of ivars etc. @@ -137,7 +135,7 @@ public: // clear out for next method. SynthesizedProperties.clear(); - SelfD = 0; + SelfD = nullptr; Removables.clear(); return true; } diff --git a/lib/ARCMigrate/TransformActions.cpp b/lib/ARCMigrate/TransformActions.cpp index 2fd0619df9f8..6d178bea0907 100644 --- a/lib/ARCMigrate/TransformActions.cpp +++ b/lib/ARCMigrate/TransformActions.cpp @@ -601,7 +601,7 @@ TransformActions::RewriteReceiver::~RewriteReceiver() { } TransformActions::TransformActions(DiagnosticsEngine &diag, CapturedDiagList &capturedDiags, ASTContext &ctx, Preprocessor &PP) - : Diags(diag), CapturedDiags(capturedDiags), ReportedErrors(false) { + : Diags(diag), CapturedDiags(capturedDiags) { Impl = new TransformActionsImpl(capturedDiags, ctx, PP); } @@ -673,60 +673,24 @@ void TransformActions::applyRewrites(RewriteReceiver &receiver) { static_cast<TransformActionsImpl*>(Impl)->applyRewrites(receiver); } -void TransformActions::reportError(StringRef error, SourceLocation loc, - SourceRange range) { - assert(!static_cast<TransformActionsImpl*>(Impl)->isInTransaction() && +DiagnosticBuilder TransformActions::report(SourceLocation loc, unsigned diagId, + SourceRange range) { + assert(!static_cast<TransformActionsImpl *>(Impl)->isInTransaction() && "Errors should be emitted out of a transaction"); - - SourceManager &SM = static_cast<TransformActionsImpl*>(Impl)-> - getASTContext().getSourceManager(); - if (SM.isInSystemHeader(SM.getExpansionLoc(loc))) - return; - - // FIXME: Use a custom category name to distinguish rewriter errors. - std::string rewriteErr = "[rewriter] "; - rewriteErr += error; - unsigned diagID - = Diags.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Error, - rewriteErr); - Diags.Report(loc, diagID) << range; - ReportedErrors = true; + return Diags.Report(loc, diagId) << range; } -void TransformActions::reportWarning(StringRef warning, SourceLocation loc, +void TransformActions::reportError(StringRef message, SourceLocation loc, SourceRange range) { - assert(!static_cast<TransformActionsImpl*>(Impl)->isInTransaction() && - "Warning should be emitted out of a transaction"); - - SourceManager &SM = static_cast<TransformActionsImpl*>(Impl)-> - getASTContext().getSourceManager(); - if (SM.isInSystemHeader(SM.getExpansionLoc(loc))) - return; - - // FIXME: Use a custom category name to distinguish rewriter errors. - std::string rewriterWarn = "[rewriter] "; - rewriterWarn += warning; - unsigned diagID - = Diags.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Warning, - rewriterWarn); - Diags.Report(loc, diagID) << range; + report(loc, diag::err_mt_message, range) << message; } -void TransformActions::reportNote(StringRef note, SourceLocation loc, - SourceRange range) { - assert(!static_cast<TransformActionsImpl*>(Impl)->isInTransaction() && - "Errors should be emitted out of a transaction"); - - SourceManager &SM = static_cast<TransformActionsImpl*>(Impl)-> - getASTContext().getSourceManager(); - if (SM.isInSystemHeader(SM.getExpansionLoc(loc))) - return; +void TransformActions::reportWarning(StringRef message, SourceLocation loc, + SourceRange range) { + report(loc, diag::warn_mt_message, range) << message; +} - // FIXME: Use a custom category name to distinguish rewriter errors. - std::string rewriteNote = "[rewriter] "; - rewriteNote += note; - unsigned diagID - = Diags.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Note, - rewriteNote); - Diags.Report(loc, diagID) << range; +void TransformActions::reportNote(StringRef message, SourceLocation loc, + SourceRange range) { + report(loc, diag::note_mt_message, range) << message; } diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp index 679b924ba009..6ff7b6b9db87 100644 --- a/lib/ARCMigrate/Transforms.cpp +++ b/lib/ARCMigrate/Transforms.cpp @@ -88,7 +88,7 @@ bool trans::isPlusOne(const Expr *E) { if (const CallExpr * callE = dyn_cast<CallExpr>(E->IgnoreParenCasts())) { if (const FunctionDecl *FD = callE->getDirectCallee()) { - if (FD->getAttr<CFReturnsRetainedAttr>()) + if (FD->hasAttr<CFReturnsRetainedAttr>()) return true; if (FD->isGlobal() && @@ -264,9 +264,8 @@ public: } bool VisitCompoundStmt(CompoundStmt *S) { - for (CompoundStmt::body_iterator - I = S->body_begin(), E = S->body_end(); I != E; ++I) - mark(*I); + for (auto *I : S->body()) + mark(I); return true; } @@ -414,8 +413,7 @@ bool MigrationContext::rewritePropertyAttribute(StringRef fromAttr, if (tok.isNot(tok::at)) return false; lexer.LexFromRawLexer(tok); if (tok.isNot(tok::raw_identifier)) return false; - if (StringRef(tok.getRawIdentifierData(), tok.getLength()) - != "property") + if (tok.getRawIdentifier() != "property") return false; lexer.LexFromRawLexer(tok); if (tok.isNot(tok::l_paren)) return false; @@ -431,8 +429,7 @@ bool MigrationContext::rewritePropertyAttribute(StringRef fromAttr, while (1) { if (tok.isNot(tok::raw_identifier)) return false; - StringRef ident(tok.getRawIdentifierData(), tok.getLength()); - if (ident == fromAttr) { + if (tok.getRawIdentifier() == fromAttr) { if (!toAttr.empty()) { Pass.TA.replaceText(tok.getLocation(), fromAttr, toAttr); return true; @@ -497,8 +494,7 @@ bool MigrationContext::addPropertyAttribute(StringRef attr, if (tok.isNot(tok::at)) return false; lexer.LexFromRawLexer(tok); if (tok.isNot(tok::raw_identifier)) return false; - if (StringRef(tok.getRawIdentifierData(), tok.getLength()) - != "property") + if (tok.getRawIdentifier() != "property") return false; lexer.LexFromRawLexer(tok); @@ -538,15 +534,12 @@ static void GCRewriteFinalize(MigrationPass &pass) { impl_iterator; for (impl_iterator I = impl_iterator(DC->decls_begin()), E = impl_iterator(DC->decls_end()); I != E; ++I) { - for (ObjCImplementationDecl::instmeth_iterator - MI = I->instmeth_begin(), - ME = I->instmeth_end(); MI != ME; ++MI) { - ObjCMethodDecl *MD = *MI; + for (const auto *MD : I->instance_methods()) { if (!MD->hasBody()) continue; if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { - ObjCMethodDecl *FinalizeM = MD; + const ObjCMethodDecl *FinalizeM = MD; Transaction Trans(TA); TA.insert(FinalizeM->getSourceRange().getBegin(), "#if !__has_feature(objc_arc)\n"); diff --git a/lib/ARCMigrate/Transforms.h b/lib/ARCMigrate/Transforms.h index eab5e85d56b7..12551d261d36 100644 --- a/lib/ARCMigrate/Transforms.h +++ b/lib/ARCMigrate/Transforms.h @@ -127,29 +127,29 @@ public: class PropertyRewriteTraverser : public ASTTraverser { public: - virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx); + void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) override; }; class BlockObjCVariableTraverser : public ASTTraverser { public: - virtual void traverseBody(BodyContext &BodyCtx); + void traverseBody(BodyContext &BodyCtx) override; }; class ProtectedScopeTraverser : public ASTTraverser { public: - virtual void traverseBody(BodyContext &BodyCtx); + void traverseBody(BodyContext &BodyCtx) override; }; // GC transformations class GCAttrsTraverser : public ASTTraverser { public: - virtual void traverseTU(MigrationContext &MigrateCtx); + void traverseTU(MigrationContext &MigrateCtx) override; }; class GCCollectableCallsTraverser : public ASTTraverser { public: - virtual void traverseBody(BodyContext &BodyCtx); + void traverseBody(BodyContext &BodyCtx) override; }; //===----------------------------------------------------------------------===// @@ -189,7 +189,7 @@ class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > { typedef RecursiveASTVisitor<BodyTransform<BODY_TRANS> > base; public: - BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(0) { } + BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(nullptr) { } bool TraverseStmt(Stmt *rootS) { if (rootS) |