aboutsummaryrefslogtreecommitdiff
path: root/lib/ARCMigrate/Transforms.cpp
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
commitbbdfad581fa300fa0d162d968ec14de3c95fc760 (patch)
treec468af2a59e7ce91a89022b916319c2147b60ac9 /lib/ARCMigrate/Transforms.cpp
parente8c904ff343f440e213b88e6963f5ebfbec7ae60 (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149079 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ARCMigrate/Transforms.cpp')
-rw-r--r--lib/ARCMigrate/Transforms.cpp44
1 files changed, 43 insertions, 1 deletions
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index a64124015c..91121f0245 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/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);