Index: include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- include/clang/Basic/DiagnosticDriverKinds.td +++ include/clang/Basic/DiagnosticDriverKinds.td @@ -226,6 +226,9 @@ def warn_drv_unsupported_opt_for_target : Warning< "optimization flag '%0' is not supported for target '%1'">, InGroup; +def warn_drv_unsupported_debug_info_opt_for_target : Warning< + "debug information option '%0' is not supported for target '%1'">, + InGroup; def warn_c_kext : Warning< "ignoring -fapple-kext which is valid for C++ and Objective-C++ only">; def warn_drv_input_file_unused : Warning< Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -72,6 +72,7 @@ def UnsupportedAbs : DiagGroup<"unsupported-abs">; def UnsupportedCB : DiagGroup<"unsupported-cb">; def UnsupportedGPOpt : DiagGroup<"unsupported-gpopt">; +def UnsupportedTargetOpt : DiagGroup<"unsupported-target-opt">; def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">; def NullConversion : DiagGroup<"null-conversion">; def ImplicitConversionFloatingPointToBool : Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -413,6 +413,11 @@ return llvm::DebuggerKind::GDB; } + /// Does this toolchain supports given debug info option or not. + virtual bool supportsDebugInfoOption(const llvm::opt::Arg *) const { + return true; + } + /// GetExceptionModel - Return the tool chain exception model. virtual llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList &Args) const; Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -921,10 +921,16 @@ static void RenderDebugInfoCompressionArgs(const ArgList &Args, ArgStringList &CmdArgs, - const Driver &D) { + const Driver &D, + const ToolChain &TC) { const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ); if (!A) return; + if (!TC.supportsDebugInfoOption(A)) { + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << A->getAsString(Args) << TC.getTripleString(); + return; + } if (A->getOption().getID() == options::OPT_gz) { if (llvm::zlib::isAvailable()) @@ -2867,8 +2873,15 @@ codegenoptions::DebugInfoKind &DebugInfoKind, const Arg *&SplitDWARFArg) { if (Args.hasFlag(options::OPT_fdebug_info_for_profiling, - options::OPT_fno_debug_info_for_profiling, false)) - CmdArgs.push_back("-fdebug-info-for-profiling"); + options::OPT_fno_debug_info_for_profiling, false)) { + if (TC.SupportsProfiling()) + CmdArgs.push_back("-fdebug-info-for-profiling"); + else + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << Args.getLastArg(options::OPT_fdebug_info_for_profiling) + ->getAsString(Args) + << T.str(); + } // The 'g' groups options involve a somewhat intricate sequence of decisions // about what to pass from the driver to the frontend, but by the time they @@ -2890,6 +2903,13 @@ SplitDWARFArg = Args.getLastArg(options::OPT_gsplit_dwarf); + if (SplitDWARFArg && !TC.supportsDebugInfoOption(SplitDWARFArg)) { + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << SplitDWARFArg->getAsString(Args) << T.str(); + SplitDWARFArg = nullptr; + SplitDWARFInlining = false; + } + if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) { // If the last option explicitly specified a debug-info level, use it. if (A->getOption().matches(options::OPT_gN_Group)) { @@ -2920,7 +2940,10 @@ // If a debugger tuning argument appeared, remember it. if (const Arg *A = Args.getLastArg(options::OPT_gTune_Group, options::OPT_ggdbN_Group)) { - if (A->getOption().matches(options::OPT_glldb)) + if (!TC.supportsDebugInfoOption(A)) + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << A->getAsString(Args) << T.str(); + else if (A->getOption().matches(options::OPT_glldb)) DebuggerTuning = llvm::DebuggerKind::LLDB; else if (A->getOption().matches(options::OPT_gsce)) DebuggerTuning = llvm::DebuggerKind::SCE; @@ -2937,6 +2960,14 @@ // Forward -gcodeview. EmitCodeView might have been set by CL-compatibility // argument parsing. if (EmitCodeView) { + const Arg *A = Args.getLastArg(options::OPT_gcodeview); + if (!TC.supportsDebugInfoOption(A)) { + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << A->getAsString(Args) << T.str(); + EmitCodeView = false; + } + } + if (EmitCodeView) { // DWARFVersion remains at 0 if no explicit choice was made. CmdArgs.push_back("-gcodeview"); } else if (DWARFVersion == 0 && @@ -2960,11 +2991,16 @@ // FIXME: Move backend command line options to the module. // If -gline-tables-only is the last option it wins. - if (DebugInfoKind != codegenoptions::DebugLineTablesOnly && - Args.hasArg(options::OPT_gmodules)) { - DebugInfoKind = codegenoptions::LimitedDebugInfo; - CmdArgs.push_back("-dwarf-ext-refs"); - CmdArgs.push_back("-fmodule-format=obj"); + const Arg *GModulesArg = Args.getLastArg(options::OPT_gmodules); + if (DebugInfoKind != codegenoptions::DebugLineTablesOnly && GModulesArg) { + if (TC.supportsDebugInfoOption(GModulesArg)) { + DebugInfoKind = codegenoptions::LimitedDebugInfo; + CmdArgs.push_back("-dwarf-ext-refs"); + CmdArgs.push_back("-fmodule-format=obj"); + } else { + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << GModulesArg->getAsString(Args) << T.str(); + } } // -gsplit-dwarf should turn on -g and enable the backend dwarf @@ -2992,16 +3028,21 @@ if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug) DebugInfoKind = codegenoptions::FullDebugInfo; - if (Args.hasFlag(options::OPT_gembed_source, options::OPT_gno_embed_source, false)) { + if (Args.hasFlag(options::OPT_gembed_source, options::OPT_gno_embed_source, + false)) { // Source embedding is a vendor extension to DWARF v5. By now we have // checked if a DWARF version was stated explicitly, and have otherwise // fallen back to the target default, so if this is still not at least 5 we // emit an error. + const Arg *A = Args.getLastArg(options::OPT_gembed_source); if (DWARFVersion < 5) D.Diag(diag::err_drv_argument_only_allowed_with) - << Args.getLastArg(options::OPT_gembed_source)->getAsString(Args) - << "-gdwarf-5"; - CmdArgs.push_back("-gembed-source"); + << A->getAsString(Args) << "-gdwarf-5"; + else if (!TC.supportsDebugInfoOption(A)) + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << A->getAsString(Args) << T.str(); + else + CmdArgs.push_back("-gembed-source"); } RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DWARFVersion, @@ -3009,27 +3050,50 @@ // -fdebug-macro turns on macro debug info generation. if (Args.hasFlag(options::OPT_fdebug_macro, options::OPT_fno_debug_macro, - false)) - CmdArgs.push_back("-debug-info-macro"); + false)) { + const Arg *A = Args.getLastArg(options::OPT_fdebug_macro); + if (TC.supportsDebugInfoOption(A)) + CmdArgs.push_back("-debug-info-macro"); + else + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << A->getAsString(Args) << T.str(); + } // -ggnu-pubnames turns on gnu style pubnames in the backend. if (Args.hasFlag(options::OPT_ggnu_pubnames, options::OPT_gno_gnu_pubnames, - false)) - CmdArgs.push_back("-ggnu-pubnames"); + false)) { + const Arg *A = Args.getLastArg(options::OPT_ggnu_pubnames); + if (TC.supportsDebugInfoOption(A)) + CmdArgs.push_back("-ggnu-pubnames"); + else + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << A->getAsString(Args) << T.str(); + } // -gdwarf-aranges turns on the emission of the aranges section in the // backend. // Always enabled for SCE tuning. - if (Args.hasArg(options::OPT_gdwarf_aranges) || - DebuggerTuning == llvm::DebuggerKind::SCE) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-generate-arange-section"); + const Arg *GDwarfAranges = Args.getLastArg(options::OPT_gdwarf_aranges); + if (GDwarfAranges || DebuggerTuning == llvm::DebuggerKind::SCE) { + if (TC.supportsDebugInfoOption(GDwarfAranges)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-generate-arange-section"); + } else { + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << GDwarfAranges->getAsString(Args) << T.str(); + } } if (Args.hasFlag(options::OPT_fdebug_types_section, options::OPT_fno_debug_types_section, false)) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-generate-type-units"); + const Arg *A = Args.getLastArg(options::OPT_fdebug_types_section); + if (TC.supportsDebugInfoOption(A)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-generate-type-units"); + } else { + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << A->getAsString(Args) << T.str(); + } } // Decide how to render forward declarations of template instantiations. @@ -3041,7 +3105,7 @@ if (DebuggerTuning == llvm::DebuggerKind::SCE) CmdArgs.push_back("-dwarf-explicit-import"); - RenderDebugInfoCompressionArgs(Args, CmdArgs, D); + RenderDebugInfoCompressionArgs(Args, CmdArgs, D, TC); } void Clang::ConstructJob(Compilation &C, const JobAction &JA, @@ -5379,7 +5443,7 @@ } RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion, llvm::DebuggerKind::Default); - RenderDebugInfoCompressionArgs(Args, CmdArgs, D); + RenderDebugInfoCompressionArgs(Args, CmdArgs, D, getToolChain()); // Handle -fPIC et al -- the relocation-model affects the assembler Index: lib/Driver/ToolChains/Cuda.h =================================================================== --- lib/Driver/ToolChains/Cuda.h +++ lib/Driver/ToolChains/Cuda.h @@ -158,6 +158,9 @@ bool isPIEDefault() const override { return false; } bool isPICDefaultForced() const override { return false; } bool SupportsProfiling() const override { return false; } + bool supportsDebugInfoOption(const llvm::opt::Arg *) const override { + return false; + } bool IsMathErrnoDefault() const override { return false; } void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, Index: test/Driver/cuda-unsupported-debug-options.cu =================================================================== --- /dev/null +++ test/Driver/cuda-unsupported-debug-options.cu @@ -0,0 +1,21 @@ +// REQUIRES: clang-driver +// REQUIRES: x86-registered-target +// REQUIRES: nvptx-registered-target + +// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -gz 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -fdebug-info-for-profiling 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -gsplit-dwarf 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -glldb 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -gcodeview 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -gmodules 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -gembed-source -gdwarf-5 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -fdebug-macro 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -ggnu-pubnames 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -gdwarf-aranges 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -fdebug-types-section 2>&1 | FileCheck %s +// CHECK: debug information option '{{-gz|-fdebug-info-for-profiling|-gsplit-dwarf|-glldb|-gcodeview|-gmodules|-gembed-source|-fdebug-macro|-ggnu-pubnames|-gdwarf-aranges|-fdebug-types-section}}' is not supported for target 'nvptx64-nvidia-cuda' [-Wunsupported-target-opt] +// CHECK-NOT: debug information option '{{.*}}' is not supported for target 'x86 +// CHECK: "-triple" "nvptx64-nvidia-cuda" +// CHECK-NOT: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}} +// CHECK: "-triple" "x86_64 +// CHECK-SAME: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}} Index: test/Driver/openmp-unsupported-debug-options.c =================================================================== --- /dev/null +++ test/Driver/openmp-unsupported-debug-options.c @@ -0,0 +1,21 @@ +// REQUIRES: clang-driver +// REQUIRES: x86-registered-target +// REQUIRES: nvptx-registered-target + +// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -gz 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -fdebug-info-for-profiling 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -gsplit-dwarf 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -glldb 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -gcodeview 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -gmodules 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -gembed-source -gdwarf-5 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -fdebug-macro 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -ggnu-pubnames 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -gdwarf-aranges 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -fdebug-types-section 2>&1 | FileCheck %s +// CHECK: debug information option '{{-gz|-fdebug-info-for-profiling|-gsplit-dwarf|-glldb|-gcodeview|-gmodules|-gembed-source|-fdebug-macro|-ggnu-pubnames|-gdwarf-aranges|-fdebug-types-section}}' is not supported for target 'nvptx64-nvidia-cuda' [-Wunsupported-target-opt] +// CHECK-NOT: debug information option '{{.*}}' is not supported for target 'x86 +// CHECK: "-triple" "nvptx64-nvidia-cuda" +// CHECK-NOT: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}} +// CHECK: "-triple" "x86_64 +// CHECK-SAME: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}}