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/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; def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group; +def fobjc_disable_direct_methods_for_testing : + Flag<["-"], "fobjc-disable-direct-methods-for-testing">, + Group, Flags<[CC1Option]>, + HelpText<"Ignore attribute objc_direct so that direct methods can be tested">; + def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group; def fopenmp : Flag<["-"], "fopenmp">, Group, Flags<[CC1Option, NoArgumentUnused]>, HelpText<"Parse OpenMP pragmas and generate parallel code.">, 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(); + return hasAttr() && + !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting; } bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const { 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/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/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/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