diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/ARCMigrate')
21 files changed, 564 insertions, 124 deletions
diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/ARCMT.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/ARCMT.cpp index b57d996..72f3520 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/ARCMT.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/ARCMT.cpp @@ -8,18 +8,19 @@ //===----------------------------------------------------------------------===// #include "Internals.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/Basic/DiagnosticCategories.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" +#include "clang/Lex/Preprocessor.h" #include "clang/Rewrite/Core/Rewriter.h" #include "clang/Sema/SemaDiagnostic.h" -#include "clang/Basic/DiagnosticCategories.h" -#include "clang/Lex/Preprocessor.h" -#include "llvm/Support/MemoryBuffer.h" +#include "clang/Serialization/ASTReader.h" #include "llvm/ADT/Triple.h" +#include "llvm/Support/MemoryBuffer.h" using namespace clang; using namespace arcmt; @@ -39,8 +40,9 @@ bool CapturedDiagList::clearDiagnostic(ArrayRef<unsigned> IDs, diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) { cleared = true; ListTy::iterator eraseS = I++; - while (I != List.end() && I->getLevel() == DiagnosticsEngine::Note) - ++I; + if (eraseS->getLevel() != DiagnosticsEngine::Note) + while (I != List.end() && I->getLevel() == DiagnosticsEngine::Note) + ++I; // Clear the diagnostic and any notes following it. I = List.erase(eraseS, I); continue; @@ -130,7 +132,8 @@ public: const Diagnostic &Info) { if (DiagnosticIDs::isARCDiagnostic(Info.getID()) || level >= DiagnosticsEngine::Error || level == DiagnosticsEngine::Note) { - CapturedDiags.push_back(StoredDiagnostic(level, Info)); + if (Info.getLocation().isValid()) + CapturedDiags.push_back(StoredDiagnostic(level, Info)); return; } @@ -172,8 +175,24 @@ static CompilerInvocation * createInvocationForMigration(CompilerInvocation &origCI) { OwningPtr<CompilerInvocation> CInvok; CInvok.reset(new CompilerInvocation(origCI)); - CInvok->getPreprocessorOpts().ImplicitPCHInclude = std::string(); - CInvok->getPreprocessorOpts().ImplicitPTHInclude = std::string(); + PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts(); + if (!PPOpts.ImplicitPCHInclude.empty()) { + // We can't use a PCH because it was likely built in non-ARC mode and we + // want to parse in ARC. Include the original header. + FileManager FileMgr(origCI.getFileSystemOpts()); + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags( + new DiagnosticsEngine(DiagID, &origCI.getDiagnosticOpts(), + new IgnoringDiagConsumer())); + std::string OriginalFile = + ASTReader::getOriginalSourceFile(PPOpts.ImplicitPCHInclude, + FileMgr, *Diags); + if (!OriginalFile.empty()) + PPOpts.Includes.insert(PPOpts.Includes.begin(), OriginalFile); + PPOpts.ImplicitPCHInclude.clear(); + } + // FIXME: Get the original header of a PTH as well. + CInvok->getPreprocessorOpts().ImplicitPTHInclude.clear(); std::string define = getARCMTMacroName(); define += '='; CInvok->getPreprocessorOpts().addMacroDef(define); @@ -295,7 +314,8 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI, std::vector<SourceLocation> ARCMTMacroLocs; TransformActions testAct(*Diags, capturedDiags, Ctx, Unit->getPreprocessor()); - MigrationPass pass(Ctx, OrigGCMode, Unit->getSema(), testAct, ARCMTMacroLocs); + MigrationPass pass(Ctx, OrigGCMode, Unit->getSema(), testAct, capturedDiags, + ARCMTMacroLocs); pass.setNSAllocReallocError(NoNSAllocReallocError); pass.setNoFinalizeRemoval(NoFinalizeRemoval); @@ -416,8 +436,8 @@ bool arcmt::getFileRemappingsFromFileList( bool hasErrorOccurred = false; llvm::StringMap<bool> Uniquer; - llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); - llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags( + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, new DiagnosticOptions, DiagClient, /*ShouldOwnClient=*/false)); @@ -461,7 +481,7 @@ public: ARCMTMacroTrackerPPCallbacks(std::vector<SourceLocation> &ARCMTMacroLocs) : ARCMTMacroLocs(ARCMTMacroLocs) { } - virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo *MI, + virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, SourceRange Range) { if (MacroNameTok.getIdentifierInfo()->getName() == getARCMTMacroName()) ARCMTMacroLocs.push_back(MacroNameTok.getLocation()); @@ -598,7 +618,7 @@ bool MigrationProcess::applyTransform(TransformFn trans, Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); TransformActions TA(*Diags, capturedDiags, Ctx, Unit->getPreprocessor()); MigrationPass pass(Ctx, OrigCI.getLangOpts()->getGC(), - Unit->getSema(), TA, ARCMTMacroLocs); + Unit->getSema(), TA, capturedDiags, ARCMTMacroLocs); trans(pass); diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/FileRemapper.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/FileRemapper.cpp index 28ca9a5..6a8686c 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/FileRemapper.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/FileRemapper.cpp @@ -8,12 +8,12 @@ //===----------------------------------------------------------------------===// #include "clang/ARCMigrate/FileRemapper.h" -#include "clang/Lex/PreprocessorOptions.h" -#include "clang/Basic/FileManager.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/FileManager.h" +#include "clang/Lex/PreprocessorOptions.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" -#include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" #include <fstream> diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/Internals.h b/contrib/llvm/tools/clang/lib/ARCMigrate/Internals.h index 1966a98..3690c83 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/Internals.h +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/Internals.h @@ -146,16 +146,20 @@ public: MigratorOptions MigOptions; Sema &SemaRef; TransformActions &TA; + const CapturedDiagList &CapturedDiags; std::vector<SourceLocation> &ARCMTMacroLocs; - llvm::Optional<bool> EnableCFBridgeFns; + Optional<bool> EnableCFBridgeFns; MigrationPass(ASTContext &Ctx, LangOptions::GCMode OrigGCMode, Sema &sema, TransformActions &TA, + const CapturedDiagList &capturedDiags, std::vector<SourceLocation> &ARCMTMacroLocs) : Ctx(Ctx), OrigGCMode(OrigGCMode), MigOptions(), - SemaRef(sema), TA(TA), + SemaRef(sema), TA(TA), CapturedDiags(capturedDiags), ARCMTMacroLocs(ARCMTMacroLocs) { } + 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; } diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/ObjCMT.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/ObjCMT.cpp index dfe14e2..57fac03 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/ObjCMT.cpp @@ -8,19 +8,21 @@ //===----------------------------------------------------------------------===// #include "clang/ARCMigrate/ARCMTActions.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/MultiplexConsumer.h" +#include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/NSAPI.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/Edit/Rewriters.h" -#include "clang/Edit/EditedSource.h" +#include "clang/AST/ParentMap.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/FileManager.h" #include "clang/Edit/Commit.h" +#include "clang/Edit/EditedSource.h" #include "clang/Edit/EditsReceiver.h" -#include "clang/Rewrite/Core/Rewriter.h" +#include "clang/Edit/Rewriters.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/MultiplexConsumer.h" +#include "clang/Lex/PPConditionalDirectiveRecord.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Basic/FileManager.h" +#include "clang/Rewrite/Core/Rewriter.h" #include "llvm/ADT/SmallString.h" using namespace clang; @@ -35,11 +37,11 @@ public: std::string MigrateDir; bool MigrateLiterals; bool MigrateSubscripting; - llvm::OwningPtr<NSAPI> NSAPIObj; - llvm::OwningPtr<edit::EditedSource> Editor; + OwningPtr<NSAPI> NSAPIObj; + OwningPtr<edit::EditedSource> Editor; FileRemapper &Remapper; FileManager &FileMgr; - const PreprocessingRecord *PPRec; + const PPConditionalDirectiveRecord *PPRec; bool IsOutputFile; ObjCMigrateASTConsumer(StringRef migrateDir, @@ -47,7 +49,7 @@ public: bool migrateSubscripting, FileRemapper &remapper, FileManager &fileMgr, - const PreprocessingRecord *PPRec, + const PPConditionalDirectiveRecord *PPRec, bool isOutputFile = false) : MigrateDir(migrateDir), MigrateLiterals(migrateLiterals), @@ -93,6 +95,9 @@ ObjCMigrateAction::ObjCMigrateAction(FrontendAction *WrappedAction, ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + PPConditionalDirectiveRecord * + PPRec = new PPConditionalDirectiveRecord(CompInst->getSourceManager()); + CompInst->getPreprocessor().addPPCallbacks(PPRec); ASTConsumer * WrappedConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile); ASTConsumer *MTConsumer = new ObjCMigrateASTConsumer(MigrateDir, @@ -100,7 +105,7 @@ ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, MigrateSubscripting, Remapper, CompInst->getFileManager(), - CompInst->getPreprocessor().getPreprocessingRecord()); + PPRec); ASTConsumer *Consumers[] = { MTConsumer, WrappedConsumer }; return new MultiplexConsumer(Consumers); } @@ -110,17 +115,17 @@ bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) { /*ignoreIfFilesChanges=*/true); CompInst = &CI; CI.getDiagnostics().setIgnoreAllWarnings(true); - CI.getPreprocessorOpts().DetailedRecord = true; - CI.getPreprocessorOpts().DetailedRecordConditionalDirectives = true; return true; } namespace { class ObjCMigrator : public RecursiveASTVisitor<ObjCMigrator> { ObjCMigrateASTConsumer &Consumer; + ParentMap &PMap; public: - ObjCMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { } + ObjCMigrator(ObjCMigrateASTConsumer &consumer, ParentMap &PMap) + : Consumer(consumer), PMap(PMap) { } bool shouldVisitTemplateInstantiations() const { return false; } bool shouldWalkTypesOfTypeLocs() const { return false; } @@ -128,7 +133,7 @@ public: bool VisitObjCMessageExpr(ObjCMessageExpr *E) { if (Consumer.MigrateLiterals) { edit::Commit commit(*Consumer.Editor); - edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit); + edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit, &PMap); Consumer.Editor->commit(commit); } @@ -151,6 +156,23 @@ public: return WalkUpFromObjCMessageExpr(E); } }; + +class BodyMigrator : public RecursiveASTVisitor<BodyMigrator> { + ObjCMigrateASTConsumer &Consumer; + OwningPtr<ParentMap> PMap; + +public: + BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { } + + bool shouldVisitTemplateInstantiations() const { return false; } + bool shouldWalkTypesOfTypeLocs() const { return false; } + + bool TraverseStmt(Stmt *S) { + PMap.reset(new ParentMap(S)); + ObjCMigrator(Consumer, *PMap).TraverseStmt(S); + return true; + } +}; } void ObjCMigrateASTConsumer::migrateDecl(Decl *D) { @@ -159,7 +181,7 @@ void ObjCMigrateASTConsumer::migrateDecl(Decl *D) { if (isa<ObjCMethodDecl>(D)) return; // Wait for the ObjC container declaration. - ObjCMigrator(*this).TraverseDecl(D); + BodyMigrator(*this).TraverseDecl(D); } namespace { @@ -191,13 +213,13 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { RewriteBuffer &buf = I->second; const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID); assert(file); - 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()), file->getName()); - llvm::SmallString<64> filePath(file->getName()); + SmallString<64> filePath(file->getName()); FileMgr.FixupRelativePath(filePath); Remapper.remap(filePath.str(), memBuf); } @@ -211,18 +233,19 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) { CI.getDiagnostics().setIgnoreAllWarnings(true); - CI.getPreprocessorOpts().DetailedRecord = true; - CI.getPreprocessorOpts().DetailedRecordConditionalDirectives = true; return true; } ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + PPConditionalDirectiveRecord * + PPRec = new PPConditionalDirectiveRecord(CI.getSourceManager()); + CI.getPreprocessor().addPPCallbacks(PPRec); return new ObjCMigrateASTConsumer(CI.getFrontendOpts().OutputFile, /*MigrateLiterals=*/true, /*MigrateSubscripting=*/true, Remapper, CI.getFileManager(), - CI.getPreprocessor().getPreprocessingRecord(), + PPRec, /*isOutputFile=*/true); } diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/PlistReporter.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/PlistReporter.cpp index d1bc90f..144ba2e 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/PlistReporter.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/PlistReporter.cpp @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// #include "Internals.h" -#include "clang/Lex/Lexer.h" -#include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" using namespace clang; using namespace arcmt; diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransAPIUses.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransAPIUses.cpp index 5336f85..2305b6d 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransAPIUses.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransAPIUses.cpp @@ -1,4 +1,4 @@ -//===--- TransAPIUses.cpp - Tranformations to ARC mode --------------------===// +//===--- TransAPIUses.cpp - Transformations to ARC mode -------------------===// // // The LLVM Compiler Infrastructure // diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransARCAssign.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransARCAssign.cpp index b83f85a..80bfd22 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransARCAssign.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransARCAssign.cpp @@ -1,4 +1,4 @@ -//===--- TransARCAssign.cpp - Tranformations to ARC mode ------------------===// +//===--- TransARCAssign.cpp - Transformations to ARC mode -----------------===// // // The LLVM Compiler Infrastructure // diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransAutoreleasePool.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransAutoreleasePool.cpp index 5205ce4..a2990e7 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransAutoreleasePool.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransAutoreleasePool.cpp @@ -1,4 +1,4 @@ -//===--- TransAutoreleasePool.cpp - Tranformations to ARC mode ------------===// +//===--- TransAutoreleasePool.cpp - Transformations to ARC mode -----------===// // // The LLVM Compiler Infrastructure // @@ -30,8 +30,8 @@ #include "Transforms.h" #include "Internals.h" #include "clang/AST/ASTContext.h" -#include "clang/Sema/SemaDiagnostic.h" #include "clang/Basic/SourceManager.h" +#include "clang/Sema/SemaDiagnostic.h" #include <map> using namespace clang; diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp index 2a79c9a..97c4e34 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp @@ -1,4 +1,4 @@ -//===--- TransBlockObjCVariable.cpp - Tranformations to ARC mode ----------===// +//===--- TransBlockObjCVariable.cpp - Transformations to ARC mode ---------===// // // The LLVM Compiler Infrastructure // @@ -28,6 +28,7 @@ #include "Transforms.h" #include "Internals.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" #include "clang/Basic/SourceManager.h" using namespace clang; diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp index 552cb2f..ffb638f 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp @@ -1,4 +1,4 @@ -//===--- TransEmptyStatements.cpp - Tranformations to ARC mode ------------===// +//===--- TransEmptyStatements.cpp - Transformations to ARC mode -----------===// // // The LLVM Compiler Infrastructure // diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransGCAttrs.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransGCAttrs.cpp index eec7306..d8be1ae 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransGCAttrs.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransGCAttrs.cpp @@ -63,19 +63,18 @@ public: return; TypeLoc TL = TInfo->getTypeLoc(); while (TL) { - if (const QualifiedTypeLoc *QL = dyn_cast<QualifiedTypeLoc>(&TL)) { - TL = QL->getUnqualifiedLoc(); - } else if (const AttributedTypeLoc * - Attr = dyn_cast<AttributedTypeLoc>(&TL)) { - if (handleAttr(*Attr, D)) + if (QualifiedTypeLoc QL = TL.getAs<QualifiedTypeLoc>()) { + TL = QL.getUnqualifiedLoc(); + } else if (AttributedTypeLoc Attr = TL.getAs<AttributedTypeLoc>()) { + if (handleAttr(Attr, D)) break; - TL = Attr->getModifiedLoc(); - } else if (const ArrayTypeLoc *Arr = dyn_cast<ArrayTypeLoc>(&TL)) { - TL = Arr->getElementLoc(); - } else if (const PointerTypeLoc *PT = dyn_cast<PointerTypeLoc>(&TL)) { - TL = PT->getPointeeLoc(); - } else if (const ReferenceTypeLoc *RT = dyn_cast<ReferenceTypeLoc>(&TL)) - TL = RT->getPointeeLoc(); + TL = Attr.getModifiedLoc(); + } else if (ArrayTypeLoc Arr = TL.getAs<ArrayTypeLoc>()) { + TL = Arr.getElementLoc(); + } else if (PointerTypeLoc PT = TL.getAs<PointerTypeLoc>()) { + TL = PT.getPointeeLoc(); + } else if (ReferenceTypeLoc RT = TL.getAs<ReferenceTypeLoc>()) + TL = RT.getPointeeLoc(); else break; } @@ -249,8 +248,9 @@ static void checkAllAtProps(MigrationContext &MigrateCtx, if (!TInfo) return; TypeLoc TL = TInfo->getTypeLoc(); - if (AttributedTypeLoc *ATL = dyn_cast<AttributedTypeLoc>(&TL)) { - ATLs.push_back(std::make_pair(*ATL, PD)); + if (AttributedTypeLoc ATL = + TL.getAs<AttributedTypeLoc>()) { + ATLs.push_back(std::make_pair(ATL, PD)); if (TInfo->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { hasWeak = true; } else if (TInfo->getType().getObjCLifetime() == Qualifiers::OCL_Strong) diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransGCCalls.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransGCCalls.cpp index 2ec480c..249f20f 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransGCCalls.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransGCCalls.cpp @@ -1,4 +1,4 @@ -//===--- TransGCCalls.cpp - Tranformations to ARC mode --------------------===// +//===--- TransGCCalls.cpp - Transformations to ARC mode -------------------===// // // The LLVM Compiler Infrastructure // diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransProperties.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransProperties.cpp index fdd6e88..b6ddc43 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransProperties.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransProperties.cpp @@ -1,4 +1,4 @@ -//===--- TransProperties.cpp - Tranformations to ARC mode -----------------===// +//===--- TransProperties.cpp - Transformations to ARC mode ----------------===// // // The LLVM Compiler Infrastructure // @@ -32,9 +32,9 @@ #include "Transforms.h" #include "Internals.h" -#include "clang/Sema/SemaDiagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" +#include "clang/Sema/SemaDiagnostic.h" #include <map> using namespace clang; @@ -141,10 +141,12 @@ public: AtPropDeclsTy AtExtProps; // Look through extensions. - for (ObjCCategoryDecl *Cat = iface->getCategoryList(); - Cat; Cat = Cat->getNextClassCategory()) - if (Cat->IsClassExtension()) - collectProperties(Cat, AtExtProps, &AtProps); + for (ObjCInterfaceDecl::visible_extensions_iterator + ext = iface->visible_extensions_begin(), + extEnd = iface->visible_extensions_end(); + ext != extEnd; ++ext) { + collectProperties(*ext, AtExtProps, &AtProps); + } for (AtPropDeclsTy::iterator I = AtExtProps.begin(), E = AtExtProps.end(); I != E; ++I) { @@ -226,8 +228,10 @@ private: for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { if (I->ImplD) - Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, - I->ImplD->getLocation()); + Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, + diag::err_arc_assign_property_ownership, + diag::err_arc_inconsistent_property_ownership, + I->IvarD->getLocation()); } } @@ -253,8 +257,10 @@ private: } } if (I->ImplD) - Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, - I->ImplD->getLocation()); + Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, + diag::err_arc_assign_property_ownership, + diag::err_arc_inconsistent_property_ownership, + I->IvarD->getLocation()); } } @@ -276,8 +282,10 @@ private: canUseWeak ? "__weak " : "__unsafe_unretained "); } if (I->ImplD) { - Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, - I->ImplD->getLocation()); + Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, + diag::err_arc_assign_property_ownership, + diag::err_arc_inconsistent_property_ownership, + I->IvarD->getLocation()); Pass.TA.clearDiagnostic( diag::err_arc_objc_property_default_assign_on_object, I->ImplD->getLocation()); diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransProtectedScope.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransProtectedScope.cpp new file mode 100644 index 0000000..237aa42 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransProtectedScope.cpp @@ -0,0 +1,202 @@ +//===--- TransProtectedScope.cpp - Transformations to ARC mode ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Adds brackets in case statements that "contain" initialization of retaining +// variable, thus emitting the "switch case is in protected scope" error. +// +//===----------------------------------------------------------------------===// + +#include "Transforms.h" +#include "Internals.h" +#include "clang/AST/ASTContext.h" +#include "clang/Sema/SemaDiagnostic.h" + +using namespace clang; +using namespace arcmt; +using namespace trans; + +namespace { + +class LocalRefsCollector : public RecursiveASTVisitor<LocalRefsCollector> { + SmallVectorImpl<DeclRefExpr *> &Refs; + +public: + LocalRefsCollector(SmallVectorImpl<DeclRefExpr *> &refs) + : Refs(refs) { } + + bool VisitDeclRefExpr(DeclRefExpr *E) { + if (ValueDecl *D = E->getDecl()) + if (D->getDeclContext()->getRedeclContext()->isFunctionOrMethod()) + Refs.push_back(E); + return true; + } +}; + +struct CaseInfo { + SwitchCase *SC; + SourceRange Range; + enum { + St_Unchecked, + St_CannotFix, + St_Fixed + } State; + + CaseInfo() : SC(0), State(St_Unchecked) {} + CaseInfo(SwitchCase *S, SourceRange Range) + : SC(S), Range(Range), State(St_Unchecked) {} +}; + +class CaseCollector : public RecursiveASTVisitor<CaseCollector> { + ParentMap &PMap; + SmallVectorImpl<CaseInfo> &Cases; + +public: + CaseCollector(ParentMap &PMap, SmallVectorImpl<CaseInfo> &Cases) + : PMap(PMap), Cases(Cases) { } + + bool VisitSwitchStmt(SwitchStmt *S) { + SwitchCase *Curr = S->getSwitchCaseList(); + if (!Curr) + return true; + Stmt *Parent = getCaseParent(Curr); + Curr = Curr->getNextSwitchCase(); + // Make sure all case statements are in the same scope. + while (Curr) { + if (getCaseParent(Curr) != Parent) + return true; + Curr = Curr->getNextSwitchCase(); + } + + SourceLocation NextLoc = S->getLocEnd(); + Curr = S->getSwitchCaseList(); + // We iterate over case statements in reverse source-order. + while (Curr) { + Cases.push_back(CaseInfo(Curr,SourceRange(Curr->getLocStart(), NextLoc))); + NextLoc = Curr->getLocStart(); + Curr = Curr->getNextSwitchCase(); + } + return true; + } + + Stmt *getCaseParent(SwitchCase *S) { + Stmt *Parent = PMap.getParent(S); + while (Parent && (isa<SwitchCase>(Parent) || isa<LabelStmt>(Parent))) + Parent = PMap.getParent(Parent); + return Parent; + } +}; + +class ProtectedScopeFixer { + MigrationPass &Pass; + SourceManager &SM; + SmallVector<CaseInfo, 16> Cases; + SmallVector<DeclRefExpr *, 16> LocalRefs; + +public: + ProtectedScopeFixer(BodyContext &BodyCtx) + : Pass(BodyCtx.getMigrationContext().Pass), + SM(Pass.Ctx.getSourceManager()) { + + CaseCollector(BodyCtx.getParentMap(), Cases) + .TraverseStmt(BodyCtx.getTopStmt()); + LocalRefsCollector(LocalRefs).TraverseStmt(BodyCtx.getTopStmt()); + + SourceRange BodyRange = BodyCtx.getTopStmt()->getSourceRange(); + const CapturedDiagList &DiagList = Pass.getDiags(); + // Copy the diagnostics so we don't have to worry about invaliding iterators + // from the diagnostic list. + SmallVector<StoredDiagnostic, 16> StoredDiags; + StoredDiags.append(DiagList.begin(), DiagList.end()); + SmallVectorImpl<StoredDiagnostic>::iterator + I = StoredDiags.begin(), E = StoredDiags.end(); + while (I != E) { + if (I->getID() == diag::err_switch_into_protected_scope && + isInRange(I->getLocation(), BodyRange)) { + handleProtectedScopeError(I, E); + continue; + } + ++I; + } + } + + void handleProtectedScopeError( + SmallVectorImpl<StoredDiagnostic>::iterator &DiagI, + SmallVectorImpl<StoredDiagnostic>::iterator DiagE){ + Transaction Trans(Pass.TA); + assert(DiagI->getID() == diag::err_switch_into_protected_scope); + SourceLocation ErrLoc = DiagI->getLocation(); + bool handledAllNotes = true; + ++DiagI; + for (; DiagI != DiagE && DiagI->getLevel() == DiagnosticsEngine::Note; + ++DiagI) { + if (!handleProtectedNote(*DiagI)) + handledAllNotes = false; + } + + if (handledAllNotes) + Pass.TA.clearDiagnostic(diag::err_switch_into_protected_scope, ErrLoc); + } + + bool handleProtectedNote(const StoredDiagnostic &Diag) { + assert(Diag.getLevel() == DiagnosticsEngine::Note); + + for (unsigned i = 0; i != Cases.size(); i++) { + CaseInfo &info = Cases[i]; + if (isInRange(Diag.getLocation(), info.Range)) { + + if (info.State == CaseInfo::St_Unchecked) + tryFixing(info); + assert(info.State != CaseInfo::St_Unchecked); + + if (info.State == CaseInfo::St_Fixed) { + Pass.TA.clearDiagnostic(Diag.getID(), Diag.getLocation()); + return true; + } + return false; + } + } + + return false; + } + + void tryFixing(CaseInfo &info) { + assert(info.State == CaseInfo::St_Unchecked); + if (hasVarReferencedOutside(info)) { + info.State = CaseInfo::St_CannotFix; + return; + } + + Pass.TA.insertAfterToken(info.SC->getColonLoc(), " {"); + Pass.TA.insert(info.Range.getEnd(), "}\n"); + info.State = CaseInfo::St_Fixed; + } + + bool hasVarReferencedOutside(CaseInfo &info) { + for (unsigned i = 0, e = LocalRefs.size(); i != e; ++i) { + DeclRefExpr *DRE = LocalRefs[i]; + if (isInRange(DRE->getDecl()->getLocation(), info.Range) && + !isInRange(DRE->getLocation(), info.Range)) + return true; + } + return false; + } + + bool isInRange(SourceLocation Loc, SourceRange R) { + if (Loc.isInvalid()) + return false; + return !SM.isBeforeInTranslationUnit(Loc, R.getBegin()) && + SM.isBeforeInTranslationUnit(Loc, R.getEnd()); + } +}; + +} // anonymous namespace + +void ProtectedScopeTraverser::traverseBody(BodyContext &BodyCtx) { + ProtectedScopeFixer Fix(BodyCtx); +} diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp index 91d2b39..0c8d155 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp @@ -1,4 +1,4 @@ -//===--- TransRetainReleaseDealloc.cpp - Tranformations to ARC mode -------===// +//===--- TransRetainReleaseDealloc.cpp - Transformations to ARC mode ------===// // // The LLVM Compiler Infrastructure // @@ -24,6 +24,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "clang/Sema/SemaDiagnostic.h" +#include "llvm/ADT/StringSwitch.h" using namespace clang; using namespace arcmt; @@ -161,13 +162,47 @@ public: private: /// \brief Checks for idioms where an unused -autorelease is common. /// - /// Currently only returns true for this idiom which is common in property + /// Returns true for this idiom which is common in property /// setters: /// /// [backingValue autorelease]; /// backingValue = [newValue retain]; // in general a +1 assign /// + /// For these as well: + /// + /// [[var retain] autorelease]; + /// return var; + /// bool isCommonUnusedAutorelease(ObjCMessageExpr *E) { + if (isPlusOneAssignBeforeOrAfterAutorelease(E)) + return true; + if (isReturnedAfterAutorelease(E)) + return true; + return false; + } + + bool isReturnedAfterAutorelease(ObjCMessageExpr *E) { + Expr *Rec = E->getInstanceReceiver(); + if (!Rec) + return false; + + Decl *RefD = getReferencedDecl(Rec); + if (!RefD) + return false; + + Stmt *nextStmt = getNextStmt(E); + if (!nextStmt) + return false; + + // Check for "return <variable>;". + + if (ReturnStmt *RetS = dyn_cast<ReturnStmt>(nextStmt)) + return RefD == getReferencedDecl(RetS->getRetValue()); + + return false; + } + + bool isPlusOneAssignBeforeOrAfterAutorelease(ObjCMessageExpr *E) { Expr *Rec = E->getInstanceReceiver(); if (!Rec) return false; @@ -176,6 +211,47 @@ private: if (!RefD) return false; + Stmt *prevStmt, *nextStmt; + llvm::tie(prevStmt, nextStmt) = getPreviousAndNextStmt(E); + + return isPlusOneAssignToVar(prevStmt, RefD) || + isPlusOneAssignToVar(nextStmt, RefD); + } + + bool isPlusOneAssignToVar(Stmt *S, Decl *RefD) { + if (!S) + return false; + + // Check for "RefD = [+1 retained object];". + + if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(S)) { + if (RefD != getReferencedDecl(Bop->getLHS())) + return false; + if (isPlusOneAssign(Bop)) + return true; + return false; + } + + if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) { + if (DS->isSingleDecl() && DS->getSingleDecl() == RefD) { + if (VarDecl *VD = dyn_cast<VarDecl>(RefD)) + return isPlusOne(VD->getInit()); + } + return false; + } + + return false; + } + + Stmt *getNextStmt(Expr *E) { + return getPreviousAndNextStmt(E).second; + } + + std::pair<Stmt *, Stmt *> getPreviousAndNextStmt(Expr *E) { + Stmt *prevStmt = 0, *nextStmt = 0; + if (!E) + return std::make_pair(prevStmt, nextStmt); + Stmt *OuterS = E, *InnerS; do { InnerS = OuterS; @@ -186,36 +262,34 @@ private: isa<ExprWithCleanups>(OuterS))); if (!OuterS) - return false; - - // Find next statement after the -autorelease. + return std::make_pair(prevStmt, nextStmt); Stmt::child_iterator currChildS = OuterS->child_begin(); Stmt::child_iterator childE = OuterS->child_end(); + Stmt::child_iterator prevChildS = childE; for (; currChildS != childE; ++currChildS) { if (*currChildS == InnerS) break; + prevChildS = currChildS; } + + if (prevChildS != childE) { + prevStmt = *prevChildS; + if (prevStmt) + prevStmt = prevStmt->IgnoreImplicit(); + } + if (currChildS == childE) - return false; + return std::make_pair(prevStmt, nextStmt); ++currChildS; if (currChildS == childE) - return false; + return std::make_pair(prevStmt, nextStmt); - Stmt *nextStmt = *currChildS; - if (!nextStmt) - return false; - nextStmt = nextStmt->IgnoreImplicit(); + nextStmt = *currChildS; + if (nextStmt) + nextStmt = nextStmt->IgnoreImplicit(); - // Check for "RefD = [+1 retained object];". - - if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(nextStmt)) { - if (RefD != getReferencedDecl(Bop->getLHS())) - return false; - if (isPlusOneAssign(Bop)) - return true; - } - return false; + return std::make_pair(prevStmt, nextStmt); } Decl *getReferencedDecl(Expr *E) { @@ -223,6 +297,17 @@ private: return 0; E = E->IgnoreParenCasts(); + if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) { + switch (ME->getMethodFamily()) { + case OMF_copy: + case OMF_autorelease: + case OMF_release: + case OMF_retain: + return getReferencedDecl(ME->getInstanceReceiver()); + default: + return 0; + } + } if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) return DRE->getDecl(); if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp index ac18b5d..fc4a75f 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp @@ -1,4 +1,4 @@ -//===--- TransUnbridgedCasts.cpp - Tranformations to ARC mode -------------===// +//===--- TransUnbridgedCasts.cpp - Transformations to ARC mode ------------===// // // The LLVM Compiler Infrastructure // @@ -30,13 +30,22 @@ // ----> // CFStringRef str = (__bridge CFStringRef)self; // +// Uses of Block_copy/Block_release macros are rewritten: +// +// c = Block_copy(b); +// Block_release(c); +// ----> +// c = [b copy]; +// <removed> +// //===----------------------------------------------------------------------===// #include "Transforms.h" #include "Internals.h" -#include "clang/Analysis/DomainSpecific/CocoaConventions.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" #include "clang/AST/ParentMap.h" +#include "clang/Analysis/DomainSpecific/CocoaConventions.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "clang/Sema/SemaDiagnostic.h" @@ -53,32 +62,32 @@ class UnbridgedCastRewriter : public RecursiveASTVisitor<UnbridgedCastRewriter>{ IdentifierInfo *SelfII; OwningPtr<ParentMap> StmtMap; Decl *ParentD; + Stmt *Body; + mutable OwningPtr<ExprSet> Removables; public: - UnbridgedCastRewriter(MigrationPass &pass) : Pass(pass), ParentD(0) { + UnbridgedCastRewriter(MigrationPass &pass) : Pass(pass), ParentD(0), Body(0) { SelfII = &Pass.Ctx.Idents.get("self"); } void transformBody(Stmt *body, Decl *ParentD) { this->ParentD = ParentD; + Body = body; StmtMap.reset(new ParentMap(body)); TraverseStmt(body); } bool VisitCastExpr(CastExpr *E) { - if (E->getCastKind() != CK_CPointerToObjCPointerCast - && E->getCastKind() != CK_BitCast) + if (E->getCastKind() != CK_CPointerToObjCPointerCast && + E->getCastKind() != CK_BitCast && + E->getCastKind() != CK_AnyPointerToBlockPointerCast) return true; QualType castType = E->getType(); Expr *castExpr = E->getSubExpr(); QualType castExprType = castExpr->getType(); - if (castType->isObjCObjectPointerType() && - castExprType->isObjCObjectPointerType()) - return true; - if (!castType->isObjCObjectPointerType() && - !castExprType->isObjCObjectPointerType()) + if (castType->isObjCRetainableType() == castExprType->isObjCRetainableType()) return true; bool exprRetainable = castExprType->isObjCIndirectLifetimeType(); @@ -93,7 +102,7 @@ public: if (loc.isValid() && Pass.Ctx.getSourceManager().isInSystemHeader(loc)) return true; - if (castType->isObjCObjectPointerType()) + if (castType->isObjCRetainableType()) transformNonObjCToObjCCast(E); else transformObjCToNonObjCCast(E); @@ -139,7 +148,7 @@ private: if (FD->getName() == "CFRetain" && FD->getNumParams() == 1 && FD->getParent()->isTranslationUnit() && - FD->getLinkage() == ExternalLinkage) { + FD->hasExternalLinkage()) { Expr *Arg = callE->getArg(0); if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) { const Expr *sub = ICE->getSubExpr(); @@ -262,7 +271,78 @@ private: rewriteToBridgedCast(castE, OBC_BridgeRetained, Trans); } + void getBlockMacroRanges(CastExpr *E, SourceRange &Outer, SourceRange &Inner) { + SourceManager &SM = Pass.Ctx.getSourceManager(); + SourceLocation Loc = E->getExprLoc(); + assert(Loc.isMacroID()); + SourceLocation MacroBegin, MacroEnd; + llvm::tie(MacroBegin, MacroEnd) = SM.getImmediateExpansionRange(Loc); + SourceRange SubRange = E->getSubExpr()->IgnoreParenImpCasts()->getSourceRange(); + SourceLocation InnerBegin = SM.getImmediateMacroCallerLoc(SubRange.getBegin()); + SourceLocation InnerEnd = SM.getImmediateMacroCallerLoc(SubRange.getEnd()); + + Outer = SourceRange(MacroBegin, MacroEnd); + Inner = SourceRange(InnerBegin, InnerEnd); + } + + void rewriteBlockCopyMacro(CastExpr *E) { + SourceRange OuterRange, InnerRange; + getBlockMacroRanges(E, OuterRange, InnerRange); + + Transaction Trans(Pass.TA); + Pass.TA.replace(OuterRange, InnerRange); + Pass.TA.insert(InnerRange.getBegin(), "["); + Pass.TA.insertAfterToken(InnerRange.getEnd(), " copy]"); + Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast, + diag::err_arc_cast_requires_bridge, + OuterRange); + } + + void removeBlockReleaseMacro(CastExpr *E) { + SourceRange OuterRange, InnerRange; + getBlockMacroRanges(E, OuterRange, InnerRange); + + Transaction Trans(Pass.TA); + Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast, + diag::err_arc_cast_requires_bridge, + OuterRange); + if (!hasSideEffects(E, Pass.Ctx)) { + if (tryRemoving(cast<Expr>(StmtMap->getParentIgnoreParenCasts(E)))) + return; + } + Pass.TA.replace(OuterRange, InnerRange); + } + + bool tryRemoving(Expr *E) const { + if (!Removables) { + Removables.reset(new ExprSet); + collectRemovables(Body, *Removables); + } + + if (Removables->count(E)) { + Pass.TA.removeStmt(E); + return true; + } + + return false; + } + void transformObjCToNonObjCCast(CastExpr *E) { + SourceLocation CastLoc = E->getExprLoc(); + if (CastLoc.isMacroID()) { + StringRef MacroName = Lexer::getImmediateMacroName(CastLoc, + Pass.Ctx.getSourceManager(), + Pass.Ctx.getLangOpts()); + if (MacroName == "Block_copy") { + rewriteBlockCopyMacro(E); + return; + } + if (MacroName == "Block_release") { + removeBlockReleaseMacro(E); + return; + } + } + if (isSelf(E->getSubExpr())) return rewriteToBridgedCast(E, OBC_Bridge); @@ -333,7 +413,7 @@ private: FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl())) if (FD->getName() == "CFRetain" && FD->getNumParams() == 1 && FD->getParent()->isTranslationUnit() && - FD->getLinkage() == ExternalLinkage) + FD->hasExternalLinkage()) return true; return false; @@ -350,7 +430,7 @@ private: if (arg == E || arg->IgnoreParenImpCasts() == E) break; } - if (i < callE->getNumArgs()) { + if (i < callE->getNumArgs() && i < FD->getNumParams()) { ParmVarDecl *PD = FD->getParamDecl(i); if (PD->getAttr<CFConsumedAttr>()) { isConsumed = true; diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp index 3057e39..e316c73 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp @@ -1,4 +1,4 @@ -//===--- TransUnusedInitDelegate.cpp - Tranformations to ARC mode ---------===// +//===--- TransUnusedInitDelegate.cpp - Transformations to ARC mode --------===// // // The LLVM Compiler Infrastructure // diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp index a07596d..4d088e0 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp @@ -1,4 +1,4 @@ -//===--- TransZeroOutPropsInDealloc.cpp - Tranformations to ARC mode ------===// +//===--- TransZeroOutPropsInDealloc.cpp - Transformations to ARC mode -----===// // // The LLVM Compiler Infrastructure // diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/TransformActions.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/TransformActions.cpp index 783db1c..2fd0619 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/TransformActions.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/TransformActions.cpp @@ -10,8 +10,8 @@ #include "Internals.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Expr.h" -#include "clang/Lex/Preprocessor.h" #include "clang/Basic/SourceManager.h" +#include "clang/Lex/Preprocessor.h" #include "llvm/ADT/DenseSet.h" #include <map> using namespace clang; diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.cpp b/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.cpp index 805a67d..0872195 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.cpp +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.cpp @@ -1,4 +1,4 @@ -//===--- Tranforms.cpp - Tranformations to ARC mode -----------------------===// +//===--- Transforms.cpp - Transformations to ARC mode ---------------------===// // // The LLVM Compiler Infrastructure // @@ -9,16 +9,17 @@ #include "Transforms.h" #include "Internals.h" -#include "clang/Analysis/DomainSpecific/CocoaConventions.h" #include "clang/AST/ASTContext.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/StmtVisitor.h" +#include "clang/Analysis/DomainSpecific/CocoaConventions.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Lex/Lexer.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaDiagnostic.h" -#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/StringSwitch.h" #include <map> using namespace clang; @@ -70,13 +71,22 @@ bool trans::isPlusOneAssign(const BinaryOperator *E) { if (E->getOpcode() != BO_Assign) return false; + return isPlusOne(E->getRHS()); +} + +bool trans::isPlusOne(const Expr *E) { + if (!E) + return false; + if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(E)) + E = EWC->getSubExpr(); + if (const ObjCMessageExpr * - ME = dyn_cast<ObjCMessageExpr>(E->getRHS()->IgnoreParenCasts())) + ME = dyn_cast<ObjCMessageExpr>(E->IgnoreParenCasts())) if (ME->getMethodFamily() == OMF_retain) return true; if (const CallExpr * - callE = dyn_cast<CallExpr>(E->getRHS()->IgnoreParenCasts())) { + callE = dyn_cast<CallExpr>(E->IgnoreParenCasts())) { if (const FunctionDecl *FD = callE->getDirectCallee()) { if (FD->getAttr<CFReturnsRetainedAttr>()) return true; @@ -84,7 +94,7 @@ bool trans::isPlusOneAssign(const BinaryOperator *E) { if (FD->isGlobal() && FD->getIdentifier() && FD->getParent()->isTranslationUnit() && - FD->getLinkage() == ExternalLinkage && + FD->hasExternalLinkage() && ento::cocoa::isRefType(callE->getType(), "CF", FD->getIdentifier()->getName())) { StringRef fname = FD->getIdentifier()->getName(); @@ -97,7 +107,7 @@ bool trans::isPlusOneAssign(const BinaryOperator *E) { } } - const ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(E->getRHS()); + const ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(E); while (implCE && implCE->getCastKind() == CK_BitCast) implCE = dyn_cast<ImplicitCastExpr>(implCE->getSubExpr()); @@ -188,7 +198,7 @@ bool trans::isGlobalVar(Expr *E) { E = E->IgnoreParenCasts(); if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) return DRE->getDecl()->getDeclContext()->isFileContext() && - DRE->getDecl()->getLinkage() == ExternalLinkage; + DRE->getDecl()->hasExternalLinkage(); if (ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(E)) return isGlobalVar(condOp->getTrueExpr()) && isGlobalVar(condOp->getFalseExpr()); @@ -563,6 +573,7 @@ static void traverseAST(MigrationPass &pass) { } MigrateCtx.addTraverser(new PropertyRewriteTraverser()); MigrateCtx.addTraverser(new BlockObjCVariableTraverser()); + MigrateCtx.addTraverser(new ProtectedScopeTraverser()); MigrateCtx.traverse(pass.Ctx.getTranslationUnitDecl()); } diff --git a/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h b/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h index 5d4ac94..cb7d153 100644 --- a/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h +++ b/contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h @@ -1,4 +1,4 @@ -//===-- Transforms.h - Tranformations to ARC mode ---------------*- C++ -*-===// +//===-- Transforms.h - Transformations to ARC mode --------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,8 +10,8 @@ #ifndef LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H #define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/ParentMap.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "llvm/ADT/DenseSet.h" #include "llvm/Support/SaveAndRestore.h" @@ -135,6 +135,11 @@ public: virtual void traverseBody(BodyContext &BodyCtx); }; +class ProtectedScopeTraverser : public ASTTraverser { +public: + virtual void traverseBody(BodyContext &BodyCtx); +}; + // GC transformations class GCAttrsTraverser : public ASTTraverser { @@ -156,6 +161,7 @@ bool canApplyWeak(ASTContext &Ctx, QualType type, bool AllowOnUnknownClass = false); bool isPlusOneAssign(const BinaryOperator *E); +bool isPlusOne(const Expr *E); /// \brief 'Loc' is the end of a statement range. This returns the location /// immediately after the semicolon following the statement. |