r196943 - [objcmt] Add a modernization option to infer and suggest designated initializers.
Argyrios Kyrtzidis
akyrtzi at gmail.com
Tue Dec 10 10:36:49 PST 2013
Author: akirtzidis
Date: Tue Dec 10 12:36:49 2013
New Revision: 196943
URL: http://llvm.org/viewvc/llvm-project?rev=196943&view=rev
Log:
[objcmt] Add a modernization option to infer and suggest designated initializers.
rdar://15509284
Added:
cfe/trunk/test/ARCMT/objcmt-designated-initializer.m
cfe/trunk/test/ARCMT/objcmt-designated-initializer.m.result
Modified:
cfe/trunk/include/clang/Driver/Options.td
cfe/trunk/include/clang/Frontend/FrontendOptions.h
cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=196943&r1=196942&r2=196943&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Tue Dec 10 12:36:49 2013
@@ -184,6 +184,8 @@ def objcmt_returns_innerpointer_property
HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">;
def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">, Flags<[CC1Option]>,
HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">;
+def objcmt_migrate_designated_init : Flag<["-"], "objcmt-migrate-designated-init">, Flags<[CC1Option]>,
+ HelpText<"Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods">;
def objcmt_white_list_dir_path: Joined<["-"], "objcmt-white-list-dir-path=">, Flags<[CC1Option]>,
HelpText<"Only modify files with a filename contained in the provided directory path">;
Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=196943&r1=196942&r2=196943&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Tue Dec 10 12:36:49 2013
@@ -179,10 +179,13 @@ public:
ObjCMT_ReturnsInnerPointerProperty = 0x200,
/// \brief use NS_NONATOMIC_IOSONLY for property 'atomic' attribute
ObjCMT_NsAtomicIOSOnlyProperty = 0x400,
+ /// \brief Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods.
+ ObjCMT_DesignatedInitializer = 0x800,
ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty |
ObjCMT_Annotation | ObjCMT_Instancetype |
ObjCMT_NsMacros | ObjCMT_ProtocolConformance |
- ObjCMT_NsAtomicIOSOnlyProperty),
+ ObjCMT_NsAtomicIOSOnlyProperty |
+ ObjCMT_DesignatedInitializer),
ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | ObjCMT_MigrateDecls)
};
unsigned ObjCMTAction;
Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=196943&r1=196942&r2=196943&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Tue Dec 10 12:36:49 2013
@@ -75,6 +75,10 @@ class ObjCMigrateASTConsumer : public AS
void migrateAddMethodAnnotation(ASTContext &Ctx,
const ObjCMethodDecl *MethodDecl);
+
+ void inferDesignatedInitializers(ASTContext &Ctx,
+ const ObjCImplementationDecl *ImplD);
+
public:
std::string MigrateDir;
unsigned ASTMigrateActions;
@@ -1539,6 +1543,55 @@ void ObjCMigrateASTConsumer::migrateAddM
}
namespace {
+class SuperInitChecker : public RecursiveASTVisitor<SuperInitChecker> {
+public:
+ bool shouldVisitTemplateInstantiations() const { return false; }
+ bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+ bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+ if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
+ if (E->getMethodFamily() == OMF_init)
+ return false;
+ }
+ return true;
+ }
+};
+} // anonymous namespace
+
+static bool hasSuperInitCall(const ObjCMethodDecl *MD) {
+ return !SuperInitChecker().TraverseStmt(MD->getBody());
+}
+
+void ObjCMigrateASTConsumer::inferDesignatedInitializers(
+ ASTContext &Ctx,
+ const ObjCImplementationDecl *ImplD) {
+
+ const ObjCInterfaceDecl *IFace = ImplD->getClassInterface();
+ if (!IFace || IFace->hasDesignatedInitializers())
+ return;
+ if (!Ctx.Idents.get("NS_DESIGNATED_INITIALIZER").hasMacroDefinition())
+ return;
+
+ for (ObjCImplementationDecl::instmeth_iterator
+ I = ImplD->instmeth_begin(), E = ImplD->instmeth_end(); I != E; ++I) {
+ const ObjCMethodDecl *MD = *I;
+ if (MD->isDeprecated() ||
+ MD->getMethodFamily() != OMF_init ||
+ MD->isDesignatedInitializerForTheInterface())
+ continue;
+ const ObjCMethodDecl *IFaceM = IFace->getMethod(MD->getSelector(),
+ /*isInstance=*/true);
+ if (!IFaceM)
+ continue;
+ if (hasSuperInitCall(MD)) {
+ edit::Commit commit(*Editor);
+ commit.insert(IFaceM->getLocEnd(), " NS_DESIGNATED_INITIALIZER");
+ Editor->commit(commit);
+ }
+ }
+}
+
+namespace {
class RewritesReceiver : public edit::EditsReceiver {
Rewriter &Rewrite;
@@ -1657,6 +1710,12 @@ void ObjCMigrateASTConsumer::HandleTrans
if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
migrateARCSafeAnnotation(Ctx, CDecl);
}
+
+ if (const ObjCImplementationDecl *
+ ImplD = dyn_cast<ObjCImplementationDecl>(*D)) {
+ if (ASTMigrateActions & FrontendOptions::ObjCMT_DesignatedInitializer)
+ inferDesignatedInitializers(Ctx, ImplD);
+ }
}
if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
AnnotateImplicitBridging(Ctx);
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=196943&r1=196942&r2=196943&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Tue Dec 10 12:36:49 2013
@@ -820,6 +820,8 @@ static InputKind ParseFrontendArgs(Front
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_AtomicProperty;
if (Args.hasArg(OPT_objcmt_ns_nonatomic_iosonly))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty;
+ if (Args.hasArg(OPT_objcmt_migrate_designated_init))
+ Opts.ObjCMTAction |= FrontendOptions::ObjCMT_DesignatedInitializer;
if (Args.hasArg(OPT_objcmt_migrate_all))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_MigrateDecls;
Added: cfe/trunk/test/ARCMT/objcmt-designated-initializer.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-designated-initializer.m?rev=196943&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-designated-initializer.m (added)
+++ cfe/trunk/test/ARCMT/objcmt-designated-initializer.m Tue Dec 10 12:36:49 2013
@@ -0,0 +1,44 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-designated-init %s -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t.remap
+// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-arc %s.result
+
+#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
+
+ at class NSString;
+
+ at interface B1
+-(id)init;
+ at end
+
+ at interface S1 : B1
+-(id)initWithFoo:(NSString*)foo;
+ at end
+
+ at implementation S1
+-(id)initWithFoo:(NSString*)foo
+{
+ self = [super init];
+ if (self) {
+ }
+ return self;
+}
+ at end
+
+ at interface B2
+-(id)init NS_DESIGNATED_INITIALIZER;
+ at end
+
+ at interface S2 : B2
+-(id)init;
+ at end
+
+ at implementation S2
+-(id)init
+{
+ self = [super init];
+ if (self) {
+ }
+ return self;
+}
+ at end
Added: cfe/trunk/test/ARCMT/objcmt-designated-initializer.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-designated-initializer.m.result?rev=196943&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-designated-initializer.m.result (added)
+++ cfe/trunk/test/ARCMT/objcmt-designated-initializer.m.result Tue Dec 10 12:36:49 2013
@@ -0,0 +1,44 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-designated-init %s -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t.remap
+// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-arc %s.result
+
+#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
+
+ at class NSString;
+
+ at interface B1
+-(id)init;
+ at end
+
+ at interface S1 : B1
+-(id)initWithFoo:(NSString*)foo NS_DESIGNATED_INITIALIZER;
+ at end
+
+ at implementation S1
+-(id)initWithFoo:(NSString*)foo
+{
+ self = [super init];
+ if (self) {
+ }
+ return self;
+}
+ at end
+
+ at interface B2
+-(id)init NS_DESIGNATED_INITIALIZER;
+ at end
+
+ at interface S2 : B2
+-(id)init;
+ at end
+
+ at implementation S2
+-(id)init
+{
+ self = [super init];
+ if (self) {
+ }
+ return self;
+}
+ at end
More information about the cfe-commits
mailing list