diff options
Diffstat (limited to 'lib/ARCMigrate/ARCMT.cpp')
-rw-r--r-- | lib/ARCMigrate/ARCMT.cpp | 165 |
1 files changed, 104 insertions, 61 deletions
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp index 6e1b0e535bbb..9354dc38b8c6 100644 --- a/lib/ARCMigrate/ARCMT.cpp +++ b/lib/ARCMigrate/ARCMT.cpp @@ -10,6 +10,7 @@ #include "Internals.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Frontend/Utils.h" #include "clang/AST/ASTConsumer.h" @@ -98,7 +99,7 @@ public: virtual void HandleDiagnostic(DiagnosticsEngine::Level level, const Diagnostic &Info) { - if (arcmt::isARCDiagnostic(Info.getID(), Diags) || + if (DiagnosticIDs::isARCDiagnostic(Info.getID()) || level >= DiagnosticsEngine::Error || level == DiagnosticsEngine::Note) { CapturedDiags.push_back(StoredDiagnostic(level, Info)); return; @@ -184,18 +185,19 @@ static bool HasARCRuntime(CompilerInvocation &origCI) { static CompilerInvocation * createInvocationForMigration(CompilerInvocation &origCI) { - llvm::OwningPtr<CompilerInvocation> CInvok; + OwningPtr<CompilerInvocation> CInvok; CInvok.reset(new CompilerInvocation(origCI)); CInvok->getPreprocessorOpts().ImplicitPCHInclude = std::string(); CInvok->getPreprocessorOpts().ImplicitPTHInclude = std::string(); std::string define = getARCMTMacroName(); define += '='; CInvok->getPreprocessorOpts().addMacroDef(define); - CInvok->getLangOpts().ObjCAutoRefCount = true; + CInvok->getLangOpts()->ObjCAutoRefCount = true; + CInvok->getLangOpts()->setGC(LangOptions::NonGC); CInvok->getDiagnosticOpts().ErrorLimit = 0; CInvok->getDiagnosticOpts().Warnings.push_back( "error=arc-unsafe-retained-assign"); - CInvok->getLangOpts().ObjCRuntimeHasWeak = HasARCRuntime(origCI); + CInvok->getLangOpts()->ObjCRuntimeHasWeak = HasARCRuntime(origCI); return CInvok.take(); } @@ -204,12 +206,12 @@ static void emitPremigrationErrors(const CapturedDiagList &arcDiags, const DiagnosticOptions &diagOpts, Preprocessor &PP) { TextDiagnosticPrinter printer(llvm::errs(), diagOpts); - llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); - llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags( + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, &printer, /*ShouldOwnClient=*/false)); Diags->setSourceManager(&PP.getSourceManager()); - printer.BeginSourceFile(PP.getLangOptions(), &PP); + printer.BeginSourceFile(PP.getLangOpts(), &PP); arcDiags.reportDiagnostics(*Diags); printer.EndSourceFile(); } @@ -219,33 +221,38 @@ static void emitPremigrationErrors(const CapturedDiagList &arcDiags, //===----------------------------------------------------------------------===// bool arcmt::checkForManualIssues(CompilerInvocation &origCI, - StringRef Filename, InputKind Kind, + const FrontendInputFile &Input, DiagnosticConsumer *DiagClient, bool emitPremigrationARCErrors, StringRef plistOut) { - if (!origCI.getLangOpts().ObjC1) + if (!origCI.getLangOpts()->ObjC1) return false; - std::vector<TransformFn> transforms = arcmt::getAllTransformations(); + LangOptions::GCMode OrigGCMode = origCI.getLangOpts()->getGC(); + bool NoNSAllocReallocError = origCI.getMigratorOpts().NoNSAllocReallocError; + bool NoFinalizeRemoval = origCI.getMigratorOpts().NoFinalizeRemoval; + + std::vector<TransformFn> transforms = arcmt::getAllTransformations(OrigGCMode, + NoFinalizeRemoval); assert(!transforms.empty()); - llvm::OwningPtr<CompilerInvocation> CInvok; + OwningPtr<CompilerInvocation> CInvok; CInvok.reset(createInvocationForMigration(origCI)); CInvok->getFrontendOpts().Inputs.clear(); - CInvok->getFrontendOpts().Inputs.push_back(std::make_pair(Kind, Filename)); + CInvok->getFrontendOpts().Inputs.push_back(Input); CapturedDiagList capturedDiags; assert(DiagClient); - llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); - llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags( + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false)); // Filter of all diagnostics. CaptureDiagnosticConsumer errRec(*Diags, capturedDiags); Diags->setClient(&errRec, /*ShouldOwnClient=*/false); - llvm::OwningPtr<ASTUnit> Unit( + OwningPtr<ASTUnit> Unit( ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags)); if (!Unit) return true; @@ -257,7 +264,7 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI, if (Diags->hasFatalErrorOccurred()) { Diags->Reset(); - DiagClient->BeginSourceFile(Ctx.getLangOptions(), &Unit->getPreprocessor()); + DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); capturedDiags.reportDiagnostics(*Diags); DiagClient->EndSourceFile(); return true; @@ -272,7 +279,7 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI, I = capturedDiags.begin(), E = capturedDiags.end(); I != E; ++I) arcDiags.push_back(*I); writeARCDiagsToPlist(plistOut, arcDiags, - Ctx.getSourceManager(), Ctx.getLangOptions()); + Ctx.getSourceManager(), Ctx.getLangOpts()); } // After parsing of source files ended, we want to reuse the @@ -280,14 +287,16 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI, // We call BeginSourceFile because DiagnosticConsumer requires that // diagnostics with source range information are emitted only in between // BeginSourceFile() and EndSourceFile(). - DiagClient->BeginSourceFile(Ctx.getLangOptions(), &Unit->getPreprocessor()); + DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); // No macros will be added since we are just checking and we won't modify // source code. std::vector<SourceLocation> ARCMTMacroLocs; TransformActions testAct(*Diags, capturedDiags, Ctx, Unit->getPreprocessor()); - MigrationPass pass(Ctx, Unit->getSema(), testAct, ARCMTMacroLocs); + MigrationPass pass(Ctx, OrigGCMode, Unit->getSema(), testAct, ARCMTMacroLocs); + pass.setNSAllocReallocError(NoNSAllocReallocError); + pass.setNoFinalizeRemoval(NoFinalizeRemoval); for (unsigned i=0, e = transforms.size(); i != e; ++i) transforms[i](pass); @@ -298,7 +307,7 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI, // If we are migrating code that gets the '-fobjc-arc' flag, make sure // to remove it so that we don't get errors from normal compilation. - origCI.getLangOpts().ObjCAutoRefCount = false; + origCI.getLangOpts()->ObjCAutoRefCount = false; return capturedDiags.hasErrors() || testAct.hasReportedErrors(); } @@ -308,27 +317,31 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI, //===----------------------------------------------------------------------===// static bool applyTransforms(CompilerInvocation &origCI, - StringRef Filename, InputKind Kind, + const FrontendInputFile &Input, DiagnosticConsumer *DiagClient, StringRef outputDir, bool emitPremigrationARCErrors, StringRef plistOut) { - if (!origCI.getLangOpts().ObjC1) + if (!origCI.getLangOpts()->ObjC1) return false; + LangOptions::GCMode OrigGCMode = origCI.getLangOpts()->getGC(); + // Make sure checking is successful first. CompilerInvocation CInvokForCheck(origCI); - if (arcmt::checkForManualIssues(CInvokForCheck, Filename, Kind, DiagClient, + if (arcmt::checkForManualIssues(CInvokForCheck, Input, DiagClient, emitPremigrationARCErrors, plistOut)) return true; CompilerInvocation CInvok(origCI); CInvok.getFrontendOpts().Inputs.clear(); - CInvok.getFrontendOpts().Inputs.push_back(std::make_pair(Kind, Filename)); + CInvok.getFrontendOpts().Inputs.push_back(Input); MigrationProcess migration(CInvok, DiagClient, outputDir); + bool NoFinalizeRemoval = origCI.getMigratorOpts().NoFinalizeRemoval; - std::vector<TransformFn> transforms = arcmt::getAllTransformations(); + std::vector<TransformFn> transforms = arcmt::getAllTransformations(OrigGCMode, + NoFinalizeRemoval); assert(!transforms.empty()); for (unsigned i=0, e = transforms.size(); i != e; ++i) { @@ -336,36 +349,36 @@ static bool applyTransforms(CompilerInvocation &origCI, if (err) return true; } - llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); - llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags( + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false)); if (outputDir.empty()) { - origCI.getLangOpts().ObjCAutoRefCount = true; + origCI.getLangOpts()->ObjCAutoRefCount = true; return migration.getRemapper().overwriteOriginal(*Diags); } else { // If we are migrating code that gets the '-fobjc-arc' flag, make sure // to remove it so that we don't get errors from normal compilation. - origCI.getLangOpts().ObjCAutoRefCount = false; + origCI.getLangOpts()->ObjCAutoRefCount = false; return migration.getRemapper().flushToDisk(outputDir, *Diags); } } bool arcmt::applyTransformations(CompilerInvocation &origCI, - StringRef Filename, InputKind Kind, + const FrontendInputFile &Input, DiagnosticConsumer *DiagClient) { - return applyTransforms(origCI, Filename, Kind, DiagClient, + return applyTransforms(origCI, Input, DiagClient, StringRef(), false, StringRef()); } bool arcmt::migrateWithTemporaryFiles(CompilerInvocation &origCI, - StringRef Filename, InputKind Kind, + const FrontendInputFile &Input, DiagnosticConsumer *DiagClient, StringRef outputDir, bool emitPremigrationARCErrors, StringRef plistOut) { assert(!outputDir.empty() && "Expected output directory path"); - return applyTransforms(origCI, Filename, Kind, DiagClient, + return applyTransforms(origCI, Input, DiagClient, outputDir, emitPremigrationARCErrors, plistOut); } @@ -375,8 +388,8 @@ bool arcmt::getFileRemappings(std::vector<std::pair<std::string,std::string> > & DiagnosticConsumer *DiagClient) { assert(!outputDir.empty()); - llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); - llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags( + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false)); FileRemapper remapper; @@ -385,13 +398,51 @@ bool arcmt::getFileRemappings(std::vector<std::pair<std::string,std::string> > & if (err) return true; - CompilerInvocation CI; - remapper.applyMappings(CI); - remap = CI.getPreprocessorOpts().RemappedFiles; + PreprocessorOptions PPOpts; + remapper.applyMappings(PPOpts); + remap = PPOpts.RemappedFiles; 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; + + llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags( + new DiagnosticsEngine(DiagID, 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. //===----------------------------------------------------------------------===// @@ -478,8 +529,8 @@ MigrationProcess::MigrationProcess(const CompilerInvocation &CI, StringRef outputDir) : OrigCI(CI), DiagClient(diagClient) { if (!outputDir.empty()) { - llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); - llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags( + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false)); Remapper.initFromDisk(outputDir, *Diags, /*ignoreIfFilesChanges=*/true); } @@ -487,28 +538,28 @@ MigrationProcess::MigrationProcess(const CompilerInvocation &CI, bool MigrationProcess::applyTransform(TransformFn trans, RewriteListener *listener) { - llvm::OwningPtr<CompilerInvocation> CInvok; + OwningPtr<CompilerInvocation> CInvok; CInvok.reset(createInvocationForMigration(OrigCI)); CInvok->getDiagnosticOpts().IgnoreWarnings = true; - Remapper.applyMappings(*CInvok); + Remapper.applyMappings(CInvok->getPreprocessorOpts()); CapturedDiagList capturedDiags; std::vector<SourceLocation> ARCMTMacroLocs; assert(DiagClient); - llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); - llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags( + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false)); // Filter of all diagnostics. CaptureDiagnosticConsumer errRec(*Diags, capturedDiags); Diags->setClient(&errRec, /*ShouldOwnClient=*/false); - llvm::OwningPtr<ARCMTMacroTrackerAction> ASTAction; + OwningPtr<ARCMTMacroTrackerAction> ASTAction; ASTAction.reset(new ARCMTMacroTrackerAction(ARCMTMacroLocs)); - llvm::OwningPtr<ASTUnit> Unit( + OwningPtr<ASTUnit> Unit( ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags, ASTAction.get())); if (!Unit) @@ -522,7 +573,7 @@ bool MigrationProcess::applyTransform(TransformFn trans, if (Diags->hasFatalErrorOccurred()) { Diags->Reset(); - DiagClient->BeginSourceFile(Ctx.getLangOptions(), &Unit->getPreprocessor()); + DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); capturedDiags.reportDiagnostics(*Diags); DiagClient->EndSourceFile(); return true; @@ -533,11 +584,12 @@ bool MigrationProcess::applyTransform(TransformFn trans, // We call BeginSourceFile because DiagnosticConsumer requires that // diagnostics with source range information are emitted only in between // BeginSourceFile() and EndSourceFile(). - DiagClient->BeginSourceFile(Ctx.getLangOptions(), &Unit->getPreprocessor()); + DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); - Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOptions()); + Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); TransformActions TA(*Diags, capturedDiags, Ctx, Unit->getPreprocessor()); - MigrationPass pass(Ctx, Unit->getSema(), TA, ARCMTMacroLocs); + MigrationPass pass(Ctx, OrigCI.getLangOpts()->getGC(), + Unit->getSema(), TA, ARCMTMacroLocs); trans(pass); @@ -559,25 +611,16 @@ bool MigrationProcess::applyTransform(TransformFn trans, assert(file); std::string newFname = file->getName(); newFname += "-trans"; - llvm::SmallString<512> newText; + SmallString<512> newText; llvm::raw_svector_ostream vecOS(newText); buf.write(vecOS); vecOS.flush(); llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy( StringRef(newText.data(), newText.size()), newFname); - llvm::SmallString<64> filePath(file->getName()); + SmallString<64> filePath(file->getName()); Unit->getFileManager().FixupRelativePath(filePath); Remapper.remap(filePath.str(), memBuf); } return false; } - -//===----------------------------------------------------------------------===// -// isARCDiagnostic. -//===----------------------------------------------------------------------===// - -bool arcmt::isARCDiagnostic(unsigned diagID, DiagnosticsEngine &Diag) { - return Diag.getDiagnosticIDs()->getCategoryNumberForDiag(diagID) == - diag::DiagCat_Automatic_Reference_Counting_Issue; -} |