diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 87449760a734..1c34df05b1c5 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -692,6 +692,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { + bool KernelOrKext = Args.hasArg(options::OPT_mkernel, + options::OPT_fapple_kext); const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; @@ -876,7 +878,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.hasFlag(options::OPT_fasynchronous_unwind_tables, options::OPT_fno_asynchronous_unwind_tables, getToolChain().IsUnwindTablesDefault() && - !Args.hasArg(options::OPT_mkernel)); + !KernelOrKext); if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables, AsynchronousUnwindTables)) CmdArgs.push_back("-munwind-tables"); @@ -1035,10 +1037,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue(Args)); } + // -fhosted is default. + if (KernelOrKext || Args.hasFlag(options::OPT_ffreestanding, + options::OPT_fhosted, + false)) + CmdArgs.push_back("-ffreestanding"); + // Forward -f (flag) options which we can pass directly. Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_behavior); Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); - Args.AddLastArg(CmdArgs, options::OPT_ffreestanding); Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); // -flax-vector-conversions is default. @@ -1105,7 +1112,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fsjlj-exceptions"); // -frtti is default. - if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti)) + if (KernelOrKext || + !Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti)) CmdArgs.push_back("-fno-rtti"); // -fsigned-char is default. @@ -1119,8 +1127,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fno-threadsafe-statics"); // -fuse-cxa-atexit is default. - if (!Args.hasFlag(options::OPT_fuse_cxa_atexit, - options::OPT_fno_use_cxa_atexit)) + if (KernelOrKext || !Args.hasFlag(options::OPT_fuse_cxa_atexit, + options::OPT_fno_use_cxa_atexit)) CmdArgs.push_back("-fno-use-cxa-atexit"); // -fms-extensions=0 is default. diff --git a/clang/test/CodeGenCXX/cxx-apple-kext.cpp b/clang/test/CodeGenCXX/cxx-apple-kext.cpp new file mode 100644 index 000000000000..8d67b53657af --- /dev/null +++ b/clang/test/CodeGenCXX/cxx-apple-kext.cpp @@ -0,0 +1,36 @@ +// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 %s -flto -S -o - |\ +// RUN: FileCheck --check-prefix=CHECK-NO-KEXT %s +// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 %s -fapple-kext -flto -S -o - |\ +// RUN: FileCheck --check-prefix=CHECK-KEXT %s + +// CHECK-NO-KEXT: @_ZTI3foo = {{.*}} @_ZTVN10__cxxabiv117 +// CHECK-NO-KEXT-NOT: _GLOBAL__D_a +// CHECK-NO-KEXT: @is_hosted = global +// CHECK-NO-KEXT: call i32 @__cxa_atexit({{.*}} @_ZN3fooD1Ev +// CHECK-NO-KEXT: declare i32 @__cxa_atexit + +// CHECK-KEXT: @_ZTV3foo = +// CHECK-KEXT-NOT: @_ZTVN10__cxxabiv117 +// CHECK-KEXT-NOT: call i32 @__cxa_atexit({{.*}} @_ZN3fooD1Ev +// CHECK-KEXT-NOT: declare i32 @__cxa_atexit +// CHECK-KEXT: @is_freestanding = global +// CHECK-KEXT: _GLOBAL__D_a +// CHECK-KEXT: call void @_ZN3fooD1Ev(%class.foo* @a) + +class foo { +public: + foo(); + virtual ~foo(); +}; + +foo a; +foo::~foo() {} + +#if !(__STDC_HOSTED__ == 1) +int is_freestanding = 1; +#else +int is_hosted = 1; +#endif + +extern "C" void f1() { +}