[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