summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2012-01-26 20:57:58 +0000
committerFariborz Jahanian <fjahanian@apple.com>2012-01-26 20:57:58 +0000
commit48fd81b484adde233b524acc94276fe7a69f33aa (patch)
treead8375a117d9a186b067c208c42bd2cefe20569a /clang/lib
parent88fce10928d96bc5373c2f01ad597208fb436574 (diff)
downloadbcm5719-llvm-48fd81b484adde233b524acc94276fe7a69f33aa.tar.gz
bcm5719-llvm-48fd81b484adde233b524acc94276fe7a69f33aa.zip
objc-arc: introduce -no-finalize-removal which in gc mode,
leaves "finalize' behind and in arc mode, does not include it. This allows the migrated source to be compiled in both gc and arc mode. // rdar://10532441 llvm-svn: 149079
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/ARCMigrate/ARCMT.cpp7
-rw-r--r--clang/lib/ARCMigrate/Transforms.cpp44
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp1
3 files changed, 49 insertions, 3 deletions
diff --git a/clang/lib/ARCMigrate/ARCMT.cpp b/clang/lib/ARCMigrate/ARCMT.cpp
index cd4835ef391..f9a1a75d877 100644
--- a/clang/lib/ARCMigrate/ARCMT.cpp
+++ b/clang/lib/ARCMigrate/ARCMT.cpp
@@ -232,7 +232,8 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
bool NoNSAllocReallocError = origCI.getMigratorOpts().NoNSAllocReallocError;
bool NoFinalizeRemoval = origCI.getMigratorOpts().NoFinalizeRemoval;
- std::vector<TransformFn> transforms = arcmt::getAllTransformations(OrigGCMode);
+ std::vector<TransformFn> transforms = arcmt::getAllTransformations(OrigGCMode,
+ NoFinalizeRemoval);
assert(!transforms.empty());
llvm::OwningPtr<CompilerInvocation> CInvok;
@@ -337,8 +338,10 @@ static bool applyTransforms(CompilerInvocation &origCI,
CInvok.getFrontendOpts().Inputs.push_back(Input);
MigrationProcess migration(CInvok, DiagClient, outputDir);
+ bool NoFinalizeRemoval = origCI.getMigratorOpts().NoFinalizeRemoval;
- std::vector<TransformFn> transforms = arcmt::getAllTransformations(OrigGCMode);
+ std::vector<TransformFn> transforms = arcmt::getAllTransformations(OrigGCMode,
+ NoFinalizeRemoval);
assert(!transforms.empty());
for (unsigned i=0, e = transforms.size(); i != e; ++i) {
diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp
index a64124015cf..91121f02453 100644
--- a/clang/lib/ARCMigrate/Transforms.cpp
+++ b/clang/lib/ARCMigrate/Transforms.cpp
@@ -502,6 +502,45 @@ void MigrationContext::traverse(TranslationUnitDecl *TU) {
ASTTransform(*this).TraverseDecl(TU);
}
+static void GCRewriteFinalize(MigrationPass &pass) {
+ ASTContext &Ctx = pass.Ctx;
+ TransformActions &TA = pass.TA;
+ DeclContext *DC = Ctx.getTranslationUnitDecl();
+ Selector FinalizeSel =
+ Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize"));
+
+ typedef DeclContext::specific_decl_iterator<ObjCImplementationDecl>
+ impl_iterator;
+ for (impl_iterator I = impl_iterator(DC->decls_begin()),
+ E = impl_iterator(DC->decls_end()); I != E; ++I) {
+ for (ObjCImplementationDecl::instmeth_iterator
+ MI = (*I)->instmeth_begin(),
+ ME = (*I)->instmeth_end(); MI != ME; ++MI) {
+ ObjCMethodDecl *MD = *MI;
+ if (!MD->hasBody())
+ continue;
+
+ if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) {
+ ObjCMethodDecl *FinalizeM = MD;
+ Transaction Trans(TA);
+ TA.insert(FinalizeM->getSourceRange().getBegin(),
+ "#if !__has_feature(objc_arc)\n");
+ CharSourceRange::getTokenRange(FinalizeM->getSourceRange());
+ const SourceManager &SM = pass.Ctx.getSourceManager();
+ const LangOptions &LangOpts = pass.Ctx.getLangOptions();
+ bool Invalid;
+ std::string str = "\n#endif\n";
+ str += Lexer::getSourceText(
+ CharSourceRange::getTokenRange(FinalizeM->getSourceRange()),
+ SM, LangOpts, &Invalid);
+ TA.insertAfterToken(FinalizeM->getSourceRange().getEnd(), str);
+
+ break;
+ }
+ }
+ }
+}
+
//===----------------------------------------------------------------------===//
// getAllTransformations.
//===----------------------------------------------------------------------===//
@@ -531,9 +570,12 @@ static void independentTransforms(MigrationPass &pass) {
}
std::vector<TransformFn> arcmt::getAllTransformations(
- LangOptions::GCMode OrigGCMode) {
+ LangOptions::GCMode OrigGCMode,
+ bool NoFinalizeRemoval) {
std::vector<TransformFn> transforms;
+ if (OrigGCMode == LangOptions::GCOnly && NoFinalizeRemoval)
+ transforms.push_back(GCRewriteFinalize);
transforms.push_back(independentTransforms);
// This depends on previous transformations removing various expressions.
transforms.push_back(removeEmptyStatementsAndDeallocFinalize);
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 5a0117af5a9..a189155e12d 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1065,6 +1065,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
static bool ParseMigratorArgs(MigratorOptions &Opts, ArgList &Args) {
Opts.NoNSAllocReallocError = Args.hasArg(OPT_migrator_no_nsalloc_error);
+ Opts.NoFinalizeRemoval = Args.hasArg(OPT_migrator_no_finalize_removal);
return true;
}
OpenPOWER on IntegriCloud