Selaa lähdekoodia

Add pragma control for diagnostics and option printing (#2656)

* Add pragma control for diagnostics and option printing
* Test converting warning to error with #pragma dxc diagnostic error "..."
* Support options: -f[no-]diagnostics-show-option and -W[no-]<warning>
Tex Riddell 5 vuotta sitten
vanhempi
commit
32168eac84

+ 3 - 0
include/dxc/Support/HLSLOptions.h

@@ -144,6 +144,7 @@ public:
   bool OutputWarnings = true; // OPT_no_warnings
   bool OutputWarnings = true; // OPT_no_warnings
   bool ShowHelp = false;  // OPT_help
   bool ShowHelp = false;  // OPT_help
   bool ShowHelpHidden = false; // OPT__help_hidden
   bool ShowHelpHidden = false; // OPT__help_hidden
+  bool ShowOptionNames = false; // OPT_fdiagnostics_show_option
   bool UseColor = false; // OPT_Cc
   bool UseColor = false; // OPT_Cc
   bool UseHexLiterals = false; // OPT_Lx
   bool UseHexLiterals = false; // OPT_Lx
   bool UseInstructionByteOffsets = false; // OPT_No
   bool UseInstructionByteOffsets = false; // OPT_No
@@ -172,6 +173,8 @@ public:
   bool ResMayAlias = false; // OPT_res_may_alias
   bool ResMayAlias = false; // OPT_res_may_alias
   unsigned long ValVerMajor = UINT_MAX, ValVerMinor = UINT_MAX; // OPT_validator_version
   unsigned long ValVerMajor = UINT_MAX, ValVerMinor = UINT_MAX; // OPT_validator_version
 
 
+  std::vector<std::string> Warnings;
+
   bool IsRootSignatureProfile();
   bool IsRootSignatureProfile();
   bool IsLibraryProfile();
   bool IsLibraryProfile();
 
 

+ 10 - 8
include/dxc/Support/HLSLOptions.td

@@ -41,8 +41,8 @@ def T_Group               : OptionGroup<"<T group>">;
 def O_Group               : OptionGroup<"<O group>">, Group<CompileOnly_Group>;
 def O_Group               : OptionGroup<"<O group>">, Group<CompileOnly_Group>;
 def R_Group               : OptionGroup<"<R group>">, Group<CompileOnly_Group>;
 def R_Group               : OptionGroup<"<R group>">, Group<CompileOnly_Group>;
 def R_value_Group         : OptionGroup<"<R (with value) group>">, Group<R_Group>;
 def R_value_Group         : OptionGroup<"<R (with value) group>">, Group<R_Group>;
-def W_Group               : OptionGroup<"<W group>">, Group<CompileOnly_Group>;
-def W_value_Group         : OptionGroup<"<W (with value) group>">, Group<W_Group>;
+def W_Group               : OptionGroup<"<W group>">, Group<CompileOnly_Group>, HelpText<"Warning Options">;
+def W_value_Group         : OptionGroup<"<W (with value) group>">, Group<W_Group>, HelpText<"Warning Options">;
 def d_Group               : OptionGroup<"<d group>">;
 def d_Group               : OptionGroup<"<d group>">;
 def f_Group               : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
 def f_Group               : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
 def f_clang_Group         : OptionGroup<"<f (clang-only) group>">, Group<CompileOnly_Group>;
 def f_clang_Group         : OptionGroup<"<f (clang-only) group>">, Group<CompileOnly_Group>;
@@ -100,10 +100,10 @@ def Odump : Flag<["-", "/"], "Odump">, Group<hlslcomp_Group>, Flags<[CoreOption]
     HelpText<"Print the optimizer commands.">;
     HelpText<"Print the optimizer commands.">;
 def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Group<hlslcore_Group>, Flags<[CoreOption]>,
 def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Group<hlslcore_Group>, Flags<[CoreOption]>,
   HelpText<"Don't emit warning for unused driver arguments">;
   HelpText<"Don't emit warning for unused driver arguments">;
-def Wall : Flag<["-"], "Wall">, Group<hlslcomp_Group>, Flags<[CoreOption]>;
-def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<hlslcomp_Group>, Flags<[CoreOption]>;
-//def W_Joined : Joined<["-"], "W">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
-//  MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
+def Wall : Flag<["-"], "Wall">, Group<W_Group>, Flags<[CoreOption]>;
+def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>, Flags<[CoreOption]>;
+def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CoreOption]>,
+  MetaVarName<"[no-]<warning>">, HelpText<"Enable/Disable the specified warning">;
 def d_Flag : Flag<["-"], "d">, Group<d_Group>;
 def d_Flag : Flag<["-"], "d">, Group<d_Group>;
 def d_Joined : Joined<["-"], "d">, Group<d_Group>;
 def d_Joined : Joined<["-"], "d">, Group<d_Group>;
 //def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<hlslcomp_Group>,
 //def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<hlslcomp_Group>,
@@ -117,8 +117,10 @@ def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>;
 def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>;
 def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>;
 def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">,
 def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">,
                                     Group<f_Group>;
                                     Group<f_Group>;
-//def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<hlslcomp_Group>,
-//    Flags<[CoreOption]>, HelpText<"Print option name with mappable diagnostics">;
+def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<hlslcomp_Group>,
+    Flags<[CoreOption]>, HelpText<"Print option name with mappable diagnostics">;
+def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group<hlslcomp_Group>,
+    Flags<[CoreOption]>, HelpText<"Do not print option name with mappable diagnostics">;
 def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category=">, Group<hlslcomp_Group>;
 def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category=">, Group<hlslcomp_Group>;
 def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<hlslcomp_Group>, Flags<[CoreOption]>;
 def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<hlslcomp_Group>, Flags<[CoreOption]>;
 
 

+ 24 - 0
lib/DxcSupport/HLSLOptions.cpp

@@ -234,6 +234,26 @@ static bool GetTargetVersionFromString(llvm::StringRef ref, unsigned *major, uns
   return true;
   return true;
 }
 }
 
 
+// Copied from CompilerInvocation since we parse our own diagnostic arguments
+static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
+                              OptSpecifier GroupWithValue,
+                              std::vector<std::string> &Diagnostics) {
+  for (Arg *A : Args.filtered(Group)) {
+    if (A->getOption().getKind() == Option::FlagClass) {
+      // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add
+      // its name (minus the "W" or "R" at the beginning) to the warning list.
+      Diagnostics.push_back(A->getOption().getName().drop_front(1));
+    } else if (A->getOption().matches(GroupWithValue)) {
+      // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic group.
+      Diagnostics.push_back(A->getOption().getName().drop_front(1).rtrim("=-"));
+    } else {
+      // Otherwise, add its value (for OPT_W_Joined and similar).
+      for (const char *Arg : A->getValues())
+        Diagnostics.emplace_back(Arg);
+    }
+  }
+}
+
 // SPIRV Change Starts
 // SPIRV Change Starts
 #ifdef ENABLE_SPIRV_CODEGEN
 #ifdef ENABLE_SPIRV_CODEGEN
 /// Checks and collects the arguments for -fvk-{b|s|t|u}-shift into *shifts.
 /// Checks and collects the arguments for -fvk-{b|s|t|u}-shift into *shifts.
@@ -444,6 +464,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   opts.OutputReflectionFile = Args.getLastArgValue(OPT_Fre);
   opts.OutputReflectionFile = Args.getLastArgValue(OPT_Fre);
   opts.OutputRootSigFile = Args.getLastArgValue(OPT_Frs);
   opts.OutputRootSigFile = Args.getLastArgValue(OPT_Frs);
   opts.OutputShaderHashFile = Args.getLastArgValue(OPT_Fsh);
   opts.OutputShaderHashFile = Args.getLastArgValue(OPT_Fsh);
+  opts.ShowOptionNames = Args.hasFlag(OPT_fdiagnostics_show_option, OPT_fno_diagnostics_show_option, true);
   opts.UseColor = Args.hasFlag(OPT_Cc, OPT_INVALID, false);
   opts.UseColor = Args.hasFlag(OPT_Cc, OPT_INVALID, false);
   opts.UseInstructionNumbers = Args.hasFlag(OPT_Ni, OPT_INVALID, false);
   opts.UseInstructionNumbers = Args.hasFlag(OPT_Ni, OPT_INVALID, false);
   opts.UseInstructionByteOffsets = Args.hasFlag(OPT_No, OPT_INVALID, false);
   opts.UseInstructionByteOffsets = Args.hasFlag(OPT_No, OPT_INVALID, false);
@@ -723,6 +744,9 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
     return 1;
     return 1;
   }
   }
 
 
+  addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, opts.Warnings);
+
+
     // SPIRV Change Starts
     // SPIRV Change Starts
 #ifdef ENABLE_SPIRV_CODEGEN
 #ifdef ENABLE_SPIRV_CODEGEN
   opts.GenSPIRV = Args.hasFlag(OPT_spirv, OPT_INVALID, false);
   opts.GenSPIRV = Args.hasFlag(OPT_spirv, OPT_INVALID, false);

+ 1 - 0
tools/clang/lib/Lex/Pragma.cpp

@@ -1435,6 +1435,7 @@ void Preprocessor::RegisterBuiltinPragmas() {
     // TODO: add HLSL-specific pragma handlers
     // TODO: add HLSL-specific pragma handlers
     AddPragmaHandler(new PragmaOnceHandler());
     AddPragmaHandler(new PragmaOnceHandler());
     AddPragmaHandler(new PragmaMarkHandler());
     AddPragmaHandler(new PragmaMarkHandler());
+    AddPragmaHandler("dxc", new PragmaDiagnosticHandler("dxc"));
     AddPragmaHandler(new PragmaMessageHandler(PPCallbacks::PMK_Message));
     AddPragmaHandler(new PragmaMessageHandler(PPCallbacks::PMK_Message));
     return;
     return;
   }
   }

+ 24 - 0
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/warnings/disable-warning-with-option.hlsl

@@ -0,0 +1,24 @@
+// RUN: %dxc -T vs_6_0 -Wno-parentheses-equality -Wno-conversion %s | FileCheck %s
+
+// Make sure the specified warnings get turned off
+
+float4 foo;
+
+// This function has no output semantic on purpose in order to produce an error,
+// otherwise, the warnings will not be captured in the output for FileCheck.
+float main() {
+  float4 x = foo;
+
+// CHECK-NOT: equality comparison with extraneous parentheses
+  if ((x.y == 0))
+  {
+
+// CHECK-NOT: implicit truncation of vector type
+    return x;
+
+  }
+  return x.y;
+
+}
+
+// CHECK: error: Semantic must be defined

+ 30 - 0
tools/clang/test/HLSLFileCheck/hlsl/diagnostics/warnings/show-option-names.hlsl

@@ -0,0 +1,30 @@
+// RUN: %dxc -T vs_6_0 %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHK_OPTION
+// RUN: %dxc -T vs_6_0 -fdiagnostics-show-option %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHK_OPTION
+// RUN: %dxc -T vs_6_0 -fno-diagnostics-show-option %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHK_NO_OPTION
+
+// Make sure the option name for the warning is printed.
+
+float4 foo;
+
+// This function has no output semantic on purpose in order to produce an error,
+// otherwise, the warnings will not be captured in the output for FileCheck.
+float main() {
+  float4 x = foo;
+
+// CHECK: equality comparison with extraneous parentheses
+// CHK_OPTION: -Wparentheses-equality
+// CHK_NO_OPTION-NOT
+  if ((x.y == 0))
+  {
+
+// CHECK: implicit truncation of vector type
+// CHK_OPTION: -Wconversion
+// CHK_NO_OPTION-NOT: -Wconversion
+    return x;
+
+  }
+  return x.y;
+
+}
+
+// CHECK: error: Semantic must be defined

+ 30 - 0
tools/clang/test/HLSLFileCheck/hlsl/preprocessor/pragma/pragma-diagnostic.hlsl

@@ -0,0 +1,30 @@
+// RUN: %dxc -T vs_6_0 %s | FileCheck %s
+
+// Verify pragma control for warnings, plus push/pop behavior
+
+float4 foo;
+
+float main() : OUT {
+  float4 x = foo;
+
+#pragma dxc diagnostic push
+// CHECK-NOT: equality comparison with extraneous parentheses
+#pragma dxc diagnostic ignored "-Wparentheses-equality"
+  if ((x.y == 0))
+  {
+// CHECK: error: implicit truncation of vector type
+#pragma dxc diagnostic error "-Wconversion"
+    return x;
+  }
+#pragma dxc diagnostic pop
+
+// Verify restoration of diagnostics
+
+// CHECK: warning: equality comparison with extraneous parentheses
+  if ((x.z == 0))
+  {
+// CHECK: warning: implicit truncation of vector type
+    return x.yzwx;
+  }
+
+}

+ 2 - 0
tools/clang/tools/dxcompiler/dxcompilerobj.cpp

@@ -992,6 +992,8 @@ public:
       ? hlsl::DXIL::kNewLayoutString
       ? hlsl::DXIL::kNewLayoutString
       : hlsl::DXIL::kLegacyLayoutString;
       : hlsl::DXIL::kLegacyLayoutString;
     compiler.HlslLangExtensions = helper;
     compiler.HlslLangExtensions = helper;
+    compiler.getDiagnosticOpts().ShowOptionNames = Opts.ShowOptionNames ? 1 : 0;
+    compiler.getDiagnosticOpts().Warnings = std::move(Opts.Warnings);
     compiler.createDiagnostics(diagPrinter, false);
     compiler.createDiagnostics(diagPrinter, false);
     // don't output warning to stderr/file if "/no-warnings" is present.
     // don't output warning to stderr/file if "/no-warnings" is present.
     compiler.getDiagnostics().setIgnoreAllWarnings(!Opts.OutputWarnings);
     compiler.getDiagnostics().setIgnoreAllWarnings(!Opts.OutputWarnings);