[TableGen] Allow references to class template arguments in defvar
authorwangpc <pc.wang@linux.alibaba.com>
Fri, 14 Apr 2023 03:07:29 +0000 (11:07 +0800)
committerwangpc <pc.wang@linux.alibaba.com>
Fri, 14 Apr 2023 03:12:35 +0000 (11:12 +0800)
We can't refer to template arguments for defvar statements in class
definitions, or it will report some errors like:

```
error: Variable not defined: 'xxx'.
```

The key point here is we used to pass nullptr to `ParseValue` in
`ParseDefvar`. As a result, we can't refer to template arguments
since `CurRec` is nullptr in `ParseIDValue`.

So we add an argument `CurRec` to `ParseDefvar` and provide it
when parsing defvar statements in class definitions.

Reviewed By: tra, simon_tatham

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

llvm/lib/TableGen/TGParser.cpp
llvm/lib/TableGen/TGParser.h
llvm/test/TableGen/defvar.td

index 6c52edc..14c529c 100644 (file)
@@ -3023,7 +3023,7 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
     return ParseAssert(nullptr, CurRec);
 
   if (Lex.getCode() == tgtok::Defvar)
-    return ParseDefvar();
+    return ParseDefvar(CurRec);
 
   if (Lex.getCode() != tgtok::Let) {
     if (!ParseDeclaration(CurRec, false))
@@ -3254,7 +3254,7 @@ bool TGParser::ParseDefset() {
 ///
 ///   Defvar ::= DEFVAR Id '=' Value ';'
 ///
-bool TGParser::ParseDefvar() {
+bool TGParser::ParseDefvar(Record *CurRec) {
   assert(Lex.getCode() == tgtok::Defvar);
   Lex.Lex(); // Eat the 'defvar' token
 
@@ -3273,7 +3273,7 @@ bool TGParser::ParseDefvar() {
   if (!consume(tgtok::equal))
     return TokError("expected '='");
 
-  Init *Value = ParseValue(nullptr);
+  Init *Value = ParseValue(CurRec);
   if (!Value)
     return true;
 
index f7271a5..63a8db0 100644 (file)
@@ -231,7 +231,7 @@ private:  // Parser methods.
   bool ParseDefm(MultiClass *CurMultiClass);
   bool ParseDef(MultiClass *CurMultiClass);
   bool ParseDefset();
-  bool ParseDefvar();
+  bool ParseDefvar(Record *CurRec = nullptr);
   bool ParseForeach(MultiClass *CurMultiClass);
   bool ParseIf(MultiClass *CurMultiClass);
   bool ParseIfBody(MultiClass *CurMultiClass, StringRef Kind);
index 4c39c37..2bf9fab 100644 (file)
@@ -18,6 +18,18 @@ defvar myvar = "foo";
 defvar myvar = "another value";
 #endif
 
+// These variables should be overrided by template arguments.
+defvar a = 2333;
+defvar b = 2333;
+class VarScopeTest<int a, int b> {
+  defvar c = !add(a, b);
+  int value = !add(c, c);
+}
+
+// CHECK: def aaa_scope_test {
+// CHECK-NEXT: int value = 10;
+def aaa_scope_test: VarScopeTest<2, 3>;
+
 multiclass Test<int x> {
   // Refer to a global variable, while inside a local scope like a multiclass.
   def _with_global_string { string s = myvar; }