erik.pilkington created this revision. erik.pilkington added reviewers: arphaman, MadCoder, rjmccall. Herald added subscribers: dexonsmith, dang, ributzka, jkorous. Herald added a reviewer: jansvoboda11. erik.pilkington requested review of this revision.
Programmers would like to be able to test direct methods by calling them from a different linkage unit or mocking them, both of which are impossible. This patch adds a flag that effectively disables the attribute, which will fix this when enabled in testable builds. rdar://71190891 https://reviews.llvm.org/D95845 Files: clang/include/clang/Basic/LangOptions.def clang/include/clang/Driver/Options.td clang/lib/AST/DeclObjC.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGenObjC/disable-direct-method.m clang/test/Driver/clang_f_opts.c Index: clang/test/Driver/clang_f_opts.c =================================================================== --- clang/test/Driver/clang_f_opts.c +++ clang/test/Driver/clang_f_opts.c @@ -568,3 +568,8 @@ // RUN: %clang -### -S -fno-temp-file %s 2>&1 | FileCheck -check-prefix=CHECK-NO-TEMP-FILE %s // CHECK-NO-TEMP-FILE: "-fno-temp-file" + +// RUN: %clang -### -xobjective-c -fobjc-disable-direct-methods-for-testing %s 2>&1 | FileCheck -check-prefix=CHECK_DISABLE_DIRECT %s +// RUN: %clang -### -xobjective-c %s 2>&1 | FileCheck -check-prefix=CHECK_NO_DISABLE_DIRECT %s +// CHECK_DISABLE_DIRECT: -fobjc-disable-direct-methods-for-testing +// CHECK_NO_DISABLE_DIRECT-NOT: -fobjc-disable-direct-methods-for-testing Index: clang/test/CodeGenObjC/disable-direct-method.m =================================================================== --- /dev/null +++ clang/test/CodeGenObjC/disable-direct-method.m @@ -0,0 +1,11 @@ +// _RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 -fobjc-disable-direct-methods-for-testing %s -o - | FileCheck %s + +@interface X +-(void)m __attribute__((objc_direct)); +@end + +void f(X *x) { + [x m]; + + // CHECK: call void bitcast ({{.*}} @objc_msgSend to {{.*}}) +} Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -2350,6 +2350,9 @@ if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime)) Opts.ObjCSubscriptingLegacyRuntime = (Opts.ObjCRuntime.getKind() == ObjCRuntime::FragileMacOSX); + + if (Args.hasArg(OPT_fobjc_disable_direct_methods_for_testing)) + Opts.ObjCDisableDirectMethodsForTesting = true; } if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) { Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -3600,6 +3600,9 @@ WeakArg->render(Args, CmdArgs); } } + + if (Args.hasArg(options::OPT_fobjc_disable_direct_methods_for_testing)) + CmdArgs.push_back("-fobjc-disable-direct-methods-for-testing"); } static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args, Index: clang/lib/AST/DeclObjC.cpp =================================================================== --- clang/lib/AST/DeclObjC.cpp +++ clang/lib/AST/DeclObjC.cpp @@ -826,7 +826,8 @@ } bool ObjCMethodDecl::isDirectMethod() const { - return hasAttr<ObjCDirectAttr>(); + return hasAttr<ObjCDirectAttr>() && + !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting; } bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const { Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2135,6 +2135,11 @@ def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Group>; def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>; +def fobjc_disable_direct_methods_for_testing : + Flag<["-"], "fobjc-disable-direct-methods-for-testing">, + Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Ignore attribute objc_direct so that direct methods can be tested">; + def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>; def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>, HelpText<"Parse OpenMP pragmas and generate parallel code.">, Index: clang/include/clang/Basic/LangOptions.def =================================================================== --- clang/include/clang/Basic/LangOptions.def +++ clang/include/clang/Basic/LangOptions.def @@ -292,6 +292,8 @@ BENIGN_LANGOPT(CompatibilityQualifiedIdBlockParamTypeChecking, 1, 0, "compatibility mode for type checking block parameters " "involving qualified id types") +LANGOPT(ObjCDisableDirectMethodsForTesting, 1, 0, + "Disable recognition of objc_direct methods") LANGOPT(CFProtectionBranch , 1, 0, "Control-Flow Branch Protection enabled") LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode")
Index: clang/test/Driver/clang_f_opts.c =================================================================== --- clang/test/Driver/clang_f_opts.c +++ clang/test/Driver/clang_f_opts.c @@ -568,3 +568,8 @@ // RUN: %clang -### -S -fno-temp-file %s 2>&1 | FileCheck -check-prefix=CHECK-NO-TEMP-FILE %s // CHECK-NO-TEMP-FILE: "-fno-temp-file" + +// RUN: %clang -### -xobjective-c -fobjc-disable-direct-methods-for-testing %s 2>&1 | FileCheck -check-prefix=CHECK_DISABLE_DIRECT %s +// RUN: %clang -### -xobjective-c %s 2>&1 | FileCheck -check-prefix=CHECK_NO_DISABLE_DIRECT %s +// CHECK_DISABLE_DIRECT: -fobjc-disable-direct-methods-for-testing +// CHECK_NO_DISABLE_DIRECT-NOT: -fobjc-disable-direct-methods-for-testing Index: clang/test/CodeGenObjC/disable-direct-method.m =================================================================== --- /dev/null +++ clang/test/CodeGenObjC/disable-direct-method.m @@ -0,0 +1,11 @@ +// _RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 -fobjc-disable-direct-methods-for-testing %s -o - | FileCheck %s + +@interface X +-(void)m __attribute__((objc_direct)); +@end + +void f(X *x) { + [x m]; + + // CHECK: call void bitcast ({{.*}} @objc_msgSend to {{.*}}) +} Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -2350,6 +2350,9 @@ if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime)) Opts.ObjCSubscriptingLegacyRuntime = (Opts.ObjCRuntime.getKind() == ObjCRuntime::FragileMacOSX); + + if (Args.hasArg(OPT_fobjc_disable_direct_methods_for_testing)) + Opts.ObjCDisableDirectMethodsForTesting = true; } if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) { Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -3600,6 +3600,9 @@ WeakArg->render(Args, CmdArgs); } } + + if (Args.hasArg(options::OPT_fobjc_disable_direct_methods_for_testing)) + CmdArgs.push_back("-fobjc-disable-direct-methods-for-testing"); } static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args, Index: clang/lib/AST/DeclObjC.cpp =================================================================== --- clang/lib/AST/DeclObjC.cpp +++ clang/lib/AST/DeclObjC.cpp @@ -826,7 +826,8 @@ } bool ObjCMethodDecl::isDirectMethod() const { - return hasAttr<ObjCDirectAttr>(); + return hasAttr<ObjCDirectAttr>() && + !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting; } bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const { Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2135,6 +2135,11 @@ def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Group>; def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>; +def fobjc_disable_direct_methods_for_testing : + Flag<["-"], "fobjc-disable-direct-methods-for-testing">, + Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Ignore attribute objc_direct so that direct methods can be tested">; + def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>; def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>, HelpText<"Parse OpenMP pragmas and generate parallel code.">, Index: clang/include/clang/Basic/LangOptions.def =================================================================== --- clang/include/clang/Basic/LangOptions.def +++ clang/include/clang/Basic/LangOptions.def @@ -292,6 +292,8 @@ BENIGN_LANGOPT(CompatibilityQualifiedIdBlockParamTypeChecking, 1, 0, "compatibility mode for type checking block parameters " "involving qualified id types") +LANGOPT(ObjCDisableDirectMethodsForTesting, 1, 0, + "Disable recognition of objc_direct methods") LANGOPT(CFProtectionBranch , 1, 0, "Control-Flow Branch Protection enabled") LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode")
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits