[llvm] d968b17 - [TableGen] Emit a warning for unused template args

Cullen Rhodes via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 3 05:09:50 PDT 2021


Author: Cullen Rhodes
Date: 2021-11-03T11:55:07Z
New Revision: d968b173d33be1a5819e9f5f9a8b4258775a65ed

URL: https://github.com/llvm/llvm-project/commit/d968b173d33be1a5819e9f5f9a8b4258775a65ed
DIFF: https://github.com/llvm/llvm-project/commit/d968b173d33be1a5819e9f5f9a8b4258775a65ed.diff

LOG: [TableGen] Emit a warning for unused template args

Add a warning to TableGen for unused template arguments in classes and
multiclasses, for example:

  multiclass Foo<int x> {
    def bar;
  }

  $ llvm-tblgen foo.td

  foo.td:1:20: warning: unused template argument: Foo::x
  multiclass Foo<int x> {
                     ^
A flag '--no-warn-on-unused-template-args' is added to disable the
warning. The warning is disabled for LLVM and sub-projects if
'LLVM_ENABLE_WARNINGS=OFF'.

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D109359

Added: 
    llvm/test/TableGen/warn-unused-template-arg.td

Modified: 
    llvm/cmake/modules/TableGen.cmake
    llvm/include/llvm/TableGen/Record.h
    llvm/lib/TableGen/Main.cpp
    llvm/lib/TableGen/Record.cpp
    llvm/lib/TableGen/TGParser.cpp
    llvm/lib/TableGen/TGParser.h
    llvm/test/TableGen/2010-03-24-PrematureDefaults.td
    llvm/test/TableGen/TemplateArgRename.td
    llvm/test/TableGen/cond-subclass.td
    llvm/test/TableGen/defmclass.td
    llvm/test/TableGen/if.td
    llvm/test/TableGen/isa.td
    llvm/test/TableGen/pr8330.td

Removed: 
    


################################################################################
diff  --git a/llvm/cmake/modules/TableGen.cmake b/llvm/cmake/modules/TableGen.cmake
index 5e9e2674405ee..442b000e8a2a6 100644
--- a/llvm/cmake/modules/TableGen.cmake
+++ b/llvm/cmake/modules/TableGen.cmake
@@ -80,6 +80,10 @@ function(tablegen project ofn)
     set(tblgen_change_flag "--write-if-changed")
   endif()
 
+  if (NOT LLVM_ENABLE_WARNINGS)
+    list(APPEND LLVM_TABLEGEN_FLAGS "-no-warn-on-unused-template-args")
+  endif()
+
   # We need both _TABLEGEN_TARGET and _TABLEGEN_EXE in the  DEPENDS list
   # (both the target and the file) to have .inc files rebuilt on
   # a tablegen change, as cmake does not propagate file-level dependencies

diff  --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index 713d9375448cc..2cf6ef13092eb 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1414,6 +1414,7 @@ class RecordVal {
   SMLoc Loc; // Source location of definition of name.
   PointerIntPair<RecTy *, 2, FieldKind> TyAndKind;
   Init *Value;
+  bool IsUsed = false;
 
 public:
   RecordVal(Init *N, RecTy *T, FieldKind K);
@@ -1458,6 +1459,11 @@ class RecordVal {
   /// Set the value and source location of the field.
   bool setValue(Init *V, SMLoc NewLoc);
 
+  /// Whether this value is used. Useful for reporting warnings, for example
+  /// when a template argument is unused.
+  void setUsed(bool Used) { IsUsed = Used; }
+  bool isUsed() const { return IsUsed; }
+
   void dump() const;
 
   /// Print the value to an output stream, possibly with a semicolon.
@@ -1632,6 +1638,7 @@ class Record {
   }
 
   void checkRecordAssertions();
+  void checkUnusedTemplateArgs();
 
   bool isSubClassOf(const Record *R) const {
     for (const auto &SCPair : SuperClasses)

diff  --git a/llvm/lib/TableGen/Main.cpp b/llvm/lib/TableGen/Main.cpp
index 0b1024648b66c..762255b43136a 100644
--- a/llvm/lib/TableGen/Main.cpp
+++ b/llvm/lib/TableGen/Main.cpp
@@ -55,6 +55,10 @@ WriteIfChanged("write-if-changed", cl::desc("Only write output if it changed"));
 static cl::opt<bool>
 TimePhases("time-phases", cl::desc("Time phases of parser and backend"));
 
+static cl::opt<bool> NoWarnOnUnusedTemplateArgs(
+    "no-warn-on-unused-template-args",
+    cl::desc("Disable unused template argument warnings."));
+
 static int reportError(const char *ProgName, Twine Msg) {
   errs() << ProgName << ": " << Msg;
   errs().flush();
@@ -107,7 +111,7 @@ int llvm::TableGenMain(const char *argv0, TableGenMainFn *MainFn) {
   // it later.
   SrcMgr.setIncludeDirs(IncludeDirs);
 
-  TGParser Parser(SrcMgr, MacroNames, Records);
+  TGParser Parser(SrcMgr, MacroNames, Records, NoWarnOnUnusedTemplateArgs);
 
   if (Parser.ParseFile())
     return 1;

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index aee8b853a0d90..a81014ef6157a 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2660,6 +2660,16 @@ void Record::checkRecordAssertions() {
   }
 }
 
+// Report a warning if the record has unused template arguments.
+void Record::checkUnusedTemplateArgs() {
+  for (const Init *TA : getTemplateArgs()) {
+    const RecordVal *Arg = getValue(TA);
+    if (!Arg->isUsed())
+      PrintWarning(Arg->getLoc(),
+                   "unused template argument: " + Twine(Arg->getName()));
+  }
+}
+
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
 LLVM_DUMP_METHOD void RecordKeeper::dump() const { errs() << *this; }
 #endif

diff  --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index ed7963031b242..6ccca4d69f40a 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -874,8 +874,9 @@ Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc,
 
     Record *TemplateRec = CurMultiClass ? &CurMultiClass->Rec : CurRec;
     if (TemplateRec->isTemplateArg(TemplateArgName)) {
-      const RecordVal *RV = TemplateRec->getValue(TemplateArgName);
+      RecordVal *RV = TemplateRec->getValue(TemplateArgName);
       assert(RV && "Template arg doesn't exist??");
+      RV->setUsed(true);
       return VarInit::get(TemplateArgName, RV->getType());
     } else if (Name->getValue() == "NAME") {
       return VarInit::get(TemplateArgName, StringRecTy::get());
@@ -3346,7 +3347,12 @@ bool TGParser::ParseClass() {
     if (ParseTemplateArgList(CurRec))
       return true;
 
-  return ParseObjectBody(CurRec);
+  if (ParseObjectBody(CurRec))
+    return true;
+
+  if (!NoWarnOnUnusedTemplateArgs)
+    CurRec->checkUnusedTemplateArgs();
+  return false;
 }
 
 /// ParseLetList - Parse a non-empty list of assignment expressions into a list
@@ -3541,6 +3547,9 @@ bool TGParser::ParseMultiClass() {
     PopLocalScope(MulticlassScope);
   }
 
+  if (!NoWarnOnUnusedTemplateArgs)
+    CurMultiClass->Rec.checkUnusedTemplateArgs();
+
   CurMultiClass = nullptr;
   return false;
 }

diff  --git a/llvm/lib/TableGen/TGParser.h b/llvm/lib/TableGen/TGParser.h
index 6e3c5186e4f66..00883c858d581 100644
--- a/llvm/lib/TableGen/TGParser.h
+++ b/llvm/lib/TableGen/TGParser.h
@@ -160,10 +160,13 @@ class TGParser {
                       // exist.
   };
 
+  bool NoWarnOnUnusedTemplateArgs = false;
+
 public:
-  TGParser(SourceMgr &SM, ArrayRef<std::string> Macros,
-           RecordKeeper &records)
-    : Lex(SM, Macros), CurMultiClass(nullptr), Records(records) {}
+  TGParser(SourceMgr &SM, ArrayRef<std::string> Macros, RecordKeeper &records,
+           const bool NoWarnOnUnusedTemplateArgs = false)
+      : Lex(SM, Macros), CurMultiClass(nullptr), Records(records),
+        NoWarnOnUnusedTemplateArgs(NoWarnOnUnusedTemplateArgs) {}
 
   /// ParseFile - Main entrypoint for parsing a tblgen file.  These parser
   /// routines return true on error, or false on success.

diff  --git a/llvm/test/TableGen/2010-03-24-PrematureDefaults.td b/llvm/test/TableGen/2010-03-24-PrematureDefaults.td
index 24f6c93b3e17c..ace979ce8f5b7 100644
--- a/llvm/test/TableGen/2010-03-24-PrematureDefaults.td
+++ b/llvm/test/TableGen/2010-03-24-PrematureDefaults.td
@@ -1,4 +1,4 @@
-// RUN: llvm-tblgen %s | FileCheck %s
+// RUN: llvm-tblgen --no-warn-on-unused-template-args %s | FileCheck %s
 // XFAIL: vg_leak
 
 class A<int k, bits<2> x = 1> {

diff  --git a/llvm/test/TableGen/TemplateArgRename.td b/llvm/test/TableGen/TemplateArgRename.td
index 654b86dc03e2f..c5c24cefbd878 100644
--- a/llvm/test/TableGen/TemplateArgRename.td
+++ b/llvm/test/TableGen/TemplateArgRename.td
@@ -1,4 +1,4 @@
-// RUN: llvm-tblgen %s
+// RUN: llvm-tblgen --no-warn-on-unused-template-args %s
 // XFAIL: vg_leak
 
 // Make sure there is no collision between XX and XX.

diff  --git a/llvm/test/TableGen/cond-subclass.td b/llvm/test/TableGen/cond-subclass.td
index 9f6f6e2cb8cc6..5f31bf15afb13 100644
--- a/llvm/test/TableGen/cond-subclass.td
+++ b/llvm/test/TableGen/cond-subclass.td
@@ -1,6 +1,6 @@
 // Check that !cond with operands of 
diff erent subtypes can
 // initialize a supertype variable.
-// RUN: llvm-tblgen %s | FileCheck %s
+// RUN: llvm-tblgen --no-warn-on-unused-template-args %s | FileCheck %s
 // XFAIL: vg_leak
 
 class E<int dummy> {}

diff  --git a/llvm/test/TableGen/defmclass.td b/llvm/test/TableGen/defmclass.td
index 80f03b319426e..2a621847a338c 100644
--- a/llvm/test/TableGen/defmclass.td
+++ b/llvm/test/TableGen/defmclass.td
@@ -1,4 +1,4 @@
-// RUN: llvm-tblgen %s | FileCheck %s
+// RUN: llvm-tblgen --no-warn-on-unused-template-args %s | FileCheck %s
 // XFAIL: vg_leak
 
 class XD { bits<4> Prefix = 11; }

diff  --git a/llvm/test/TableGen/if.td b/llvm/test/TableGen/if.td
index b2ba89c8dd087..cd8a8e728df66 100644
--- a/llvm/test/TableGen/if.td
+++ b/llvm/test/TableGen/if.td
@@ -1,4 +1,4 @@
-// RUN: llvm-tblgen %s | FileCheck %s
+// RUN: llvm-tblgen --no-warn-on-unused-template-args %s | FileCheck %s
 // XFAIL: vg_leak
 
 // Support for an `!if' operator as part of a `let' statement.

diff  --git a/llvm/test/TableGen/isa.td b/llvm/test/TableGen/isa.td
index cfaacb03b71aa..e4095fb96752d 100644
--- a/llvm/test/TableGen/isa.td
+++ b/llvm/test/TableGen/isa.td
@@ -1,4 +1,4 @@
-// RUN: llvm-tblgen %s | FileCheck %s
+// RUN: llvm-tblgen --no-warn-on-unused-template-args %s | FileCheck %s
 // XFAIL: vg_leak
 
 // CHECK: --- Defs ---

diff  --git a/llvm/test/TableGen/pr8330.td b/llvm/test/TableGen/pr8330.td
index 7779b635e33cc..ceabbc50f64c1 100644
--- a/llvm/test/TableGen/pr8330.td
+++ b/llvm/test/TableGen/pr8330.td
@@ -1,4 +1,4 @@
-// RUN: llvm-tblgen %s | FileCheck %s
+// RUN: llvm-tblgen --no-warn-on-unused-template-args %s | FileCheck %s
 // XFAIL: vg_leak
 
 class Or4<bits<8> Val> {

diff  --git a/llvm/test/TableGen/warn-unused-template-arg.td b/llvm/test/TableGen/warn-unused-template-arg.td
new file mode 100644
index 0000000000000..5f76e82fc0d9a
--- /dev/null
+++ b/llvm/test/TableGen/warn-unused-template-arg.td
@@ -0,0 +1,25 @@
+// RUN: llvm-tblgen %s 2>&1 | FileCheck %s
+// RUN: llvm-tblgen --no-warn-on-unused-template-args %s 2>&1 | FileCheck %s --check-prefix=CHECK-DISABLED
+
+class UnusedClassArg<int foo> {}
+
+// CHECK: warning: unused template argument: UnusedClassArg:foo
+// CHECK-NEXT: class UnusedClassArg<int foo> {}
+// CHECK-NEXT:                          ^
+
+multiclass UnusedMultiClassArg<int foo> {
+  def bar;
+}
+
+defm : UnusedMultiClassArg<1>;
+
+// CHECK: warning: unused template argument: UnusedMultiClassArg::foo
+// CHECK-NEXT: multiclass UnusedMultiClassArg<int foo> {
+// CHECK-NEXT:                                    ^
+
+class NoWarning<int b> {
+  int a = b;
+}
+
+// CHECK-NOT: warning: unused template argument: NoWarning:b
+// CHECK-DISABLED-NOT: warning


        


More information about the llvm-commits mailing list