summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/ARCMigrate
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/ARCMigrate')
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/ARCMT.cpp48
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/FileRemapper.cpp6
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/Internals.h8
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/ObjCMT.cpp69
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/PlistReporter.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransAPIUses.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransARCAssign.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransAutoreleasePool.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp3
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransGCAttrs.cpp28
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransGCCalls.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransProperties.cpp32
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransProtectedScope.cpp202
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp125
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp108
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/TransformActions.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.cpp27
-rw-r--r--contrib/llvm/tools/clang/lib/ARCMigrate/Transforms.h10
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.
OpenPOWER on IntegriCloud