Index: clang/include/clang/Driver/ToolChain.h =================================================================== --- clang/include/clang/Driver/ToolChain.h +++ clang/include/clang/Driver/ToolChain.h @@ -381,6 +381,9 @@ /// needsProfileRT - returns true if instrumentation profile is on. static bool needsProfileRT(const llvm::opt::ArgList &Args); + /// Returns true if gcov instrumentation (-fprofile-arcs or --coverage) is on. + static bool needsGCovInstrumentation(const llvm::opt::ArgList &Args); + /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables /// by default. virtual bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const; Index: clang/lib/Driver/ToolChain.cpp =================================================================== --- clang/lib/Driver/ToolChain.cpp +++ clang/lib/Driver/ToolChain.cpp @@ -403,19 +403,23 @@ } bool ToolChain::needsProfileRT(const ArgList &Args) { - if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, - false) || + if (needsGCovInstrumentation(Args) || Args.hasArg(options::OPT_fprofile_generate) || Args.hasArg(options::OPT_fprofile_generate_EQ) || Args.hasArg(options::OPT_fprofile_instr_generate) || Args.hasArg(options::OPT_fprofile_instr_generate_EQ) || - Args.hasArg(options::OPT_fcreate_profile) || - Args.hasArg(options::OPT_coverage)) + Args.hasArg(options::OPT_fcreate_profile)) return true; return false; } +bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList &Args) { + return Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, + false) || + Args.hasArg(options::OPT_coverage); +} + Tool *ToolChain::SelectTool(const JobAction &JA) const { if (getDriver().ShouldUseClangCompiler(JA)) return getClang(); Action::ActionClass AC = JA.getKind(); Index: clang/lib/Driver/ToolChains/Darwin.cpp =================================================================== --- clang/lib/Driver/ToolChains/Darwin.cpp +++ clang/lib/Driver/ToolChains/Darwin.cpp @@ -1034,11 +1034,17 @@ // runtime, automatically export symbols necessary to implement some of the // runtime's functionality. if (hasExportSymbolDirective(Args)) { - addExportedSymbol(CmdArgs, "___llvm_profile_filename"); - addExportedSymbol(CmdArgs, "___llvm_profile_raw_version"); - addExportedSymbol(CmdArgs, "_lprofCurFilename"); + if (needsGCovInstrumentation(Args)) { + addExportedSymbol(CmdArgs, "___gcov_flush"); + addExportedSymbol(CmdArgs, "_flush_fn_list"); + addExportedSymbol(CmdArgs, "_writeout_fn_list"); + } else { + addExportedSymbol(CmdArgs, "___llvm_profile_filename"); + addExportedSymbol(CmdArgs, "___llvm_profile_raw_version"); + addExportedSymbol(CmdArgs, "_lprofCurFilename"); + addExportedSymbol(CmdArgs, "_lprofMergeValueProfData"); + } addExportedSymbol(CmdArgs, "_lprofDirMode"); - addExportedSymbol(CmdArgs, "_lprofMergeValueProfData"); } } Index: clang/test/Driver/darwin-ld.c =================================================================== --- clang/test/Driver/darwin-ld.c +++ clang/test/Driver/darwin-ld.c @@ -341,10 +341,22 @@ // RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log // PROFILE_EXPORT: "-exported_symbol" "___llvm_profile_filename" "-exported_symbol" "___llvm_profile_raw_version" "-exported_symbol" "_lprofCurFilename" // -// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -### %t.o 2> %t.log +// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate --coverage -### %t.o 2> %t.log // RUN: FileCheck -check-prefix=NO_PROFILE_EXPORT %s < %t.log // NO_PROFILE_EXPORT-NOT: "-exported_symbol" // +// RUN: %clang -target x86_64-apple-darwin12 --coverage -exported_symbols_list /dev/null -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log +// RUN: %clang -target x86_64-apple-darwin12 -fprofile-arcs -Wl,-exported_symbols_list,/dev/null -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log +// RUN: %clang -target x86_64-apple-darwin12 -fprofile-arcs -Wl,-exported_symbol,foo -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log +// RUN: %clang -target x86_64-apple-darwin12 -fprofile-arcs -Xlinker -exported_symbol -Xlinker foo -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log +// RUN: %clang -target x86_64-apple-darwin12 -fprofile-arcs -Xlinker -exported_symbols_list -Xlinker /dev/null -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log +// GCOV_EXPORT: "-exported_symbol" "___gcov_flush" +// // Check that we can pass the outliner down to the linker. // RUN: env IPHONEOS_DEPLOYMENT_TARGET=7.0 \ // RUN: %clang -target arm64-apple-darwin -moutline -### %t.o 2> %t.log Index: compiler-rt/test/profile/instrprof-darwin-exports.c =================================================================== --- compiler-rt/test/profile/instrprof-darwin-exports.c +++ compiler-rt/test/profile/instrprof-darwin-exports.c @@ -8,6 +8,9 @@ // RUN: %clang_profgen -Werror -fcoverage-mapping -Wl,-exported_symbols_list,%t.exports -o %t %s 2>&1 | tee -a %t.log // RUN: cat %t.log | count 0 +// RUN: %clang -Werror -Wl,-exported_symbols_list,%t.exports --coverage -o %t.gcov %s | tee -a %t.gcov.log +// RUN: cat %t.gcov.log | count 0 + // The default set of weak external symbols should match the set of symbols // exported by clang. See Darwin::addProfileRTLibs. @@ -16,4 +19,9 @@ // RUN: nm -jUg %t > %t.clang.exports // RUN: diff %t.default.exports %t.clang.exports +// RUN: %clang -Werror --coverage -o %t.gcov.default %s +// RUN: nm -jUg %t.gcov | grep -v __mh_execute_header > %t.gcov.exports +// RUN: nm -jUg %t.gcov.default | grep -v __mh_execute_header > %t.gcov.default.exports +// RUN: diff %t.gcov.default.exports %t.gcov.exports + int main() {}