aboutsummaryrefslogtreecommitdiff
path: root/lib/ARCMigrate
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2014-11-24 09:15:30 +0000
committerDimitry Andric <dim@FreeBSD.org>2014-11-24 09:15:30 +0000
commit9f4dbff6669c8037f3b036bcf580d14f1a4f12a5 (patch)
tree47df2c12b57214af6c31e47404b005675b8b7ffc /lib/ARCMigrate
parentf73d5f23a889b93d89ddef61ac0995df40286bb8 (diff)
downloadsrc-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.cpp87
-rw-r--r--lib/ARCMigrate/CMakeLists.txt30
-rw-r--r--lib/ARCMigrate/FileRemapper.cpp43
-rw-r--r--lib/ARCMigrate/Internals.h9
-rw-r--r--lib/ARCMigrate/ObjCMT.cpp710
-rw-r--r--lib/ARCMigrate/PlistReporter.cpp113
-rw-r--r--lib/ARCMigrate/TransAPIUses.cpp16
-rw-r--r--lib/ARCMigrate/TransAutoreleasePool.cpp8
-rw-r--r--lib/ARCMigrate/TransBlockObjCVariable.cpp7
-rw-r--r--lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp24
-rw-r--r--lib/ARCMigrate/TransGCAttrs.cpp12
-rw-r--r--lib/ARCMigrate/TransGCCalls.cpp10
-rw-r--r--lib/ARCMigrate/TransProperties.cpp31
-rw-r--r--lib/ARCMigrate/TransProtectedScope.cpp2
-rw-r--r--lib/ARCMigrate/TransRetainReleaseDealloc.cpp18
-rw-r--r--lib/ARCMigrate/TransUnbridgedCasts.cpp15
-rw-r--r--lib/ARCMigrate/TransUnusedInitDelegate.cpp2
-rw-r--r--lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp34
-rw-r--r--lib/ARCMigrate/TransformActions.cpp64
-rw-r--r--lib/ARCMigrate/Transforms.cpp23
-rw-r--r--lib/ARCMigrate/Transforms.h12
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 << "&amp;"; break;
- case '<': o << "&lt;"; break;
- case '>': o << "&gt;"; break;
- case '\'': o << "&apos;"; break;
- case '\"': o << "&quot;"; 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)