TableGen: Remove the cast-from-string-to-variable-reference feature
authorNicolai Haehnle <nhaehnle@gmail.com>
Mon, 19 Mar 2018 14:13:37 +0000 (14:13 +0000)
committerNicolai Haehnle <nhaehnle@gmail.com>
Mon, 19 Mar 2018 14:13:37 +0000 (14:13 +0000)
Summary:
Cast-from-string for records isn't going away, but cast-from-string for
variables is a pretty dodgy feature to have, especially when referencing
template arguments. It's doubtful that this ever worked in a reliable
way, and nobody seems to be using it, so let's get rid of it and get
some related cleanups.

Change-Id: I395ac8a43fef4cf98e611f2f552300d21e99b66a

Reviewers: arsenm, craig.topper, tra, MartinO

Subscribers: wdng, llvm-commits

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

llvm-svn: 327844

llvm/docs/TableGen/LangIntro.rst
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/Record.cpp
llvm/lib/TableGen/TGParser.cpp
llvm/test/TableGen/MultiClass-defm-fail.td

index c66c9da..b77dad0 100644 (file)
@@ -216,10 +216,6 @@ supported include:
 
     If the type of 'a' does not match *type*, TableGen aborts with an error.
 
-    For historical reasons, 'a' can also be the name of a variable or a
-    template argument in some cases, but this use is unreliable and is
-    discouraged.
-
     Otherwise, perform a normal type cast e.g. between an int and a bit, or
     between record types. This allows casting a record to a subclass, though if
     the types do not match, constant folding will be inhibited. !cast<string>
index 58fb6c8..09f502d 100644 (file)
@@ -744,7 +744,7 @@ public:
 
   // Fold - If possible, fold this to a simpler init.  Return this if not
   // possible to fold.
-  virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0;
+  virtual Init *Fold(Record *CurRec) const = 0;
 
   Init *getBit(unsigned Bit) const override;
 };
@@ -792,7 +792,7 @@ public:
 
   // Fold - If possible, fold this to a simpler init.  Return this if not
   // possible to fold.
-  Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const override;
+  Init *Fold(Record *CurRec) const override;
 
   Init *resolveReferences(Resolver &R) const override;
 
@@ -846,7 +846,7 @@ public:
 
   // Fold - If possible, fold this to a simpler init.  Return this if not
   // possible to fold.
-  Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const override;
+  Init *Fold(Record *CurRec) const override;
 
   Init *resolveReferences(Resolver &R) const override;
 
@@ -904,7 +904,7 @@ public:
 
   // Fold - If possible, fold this to a simpler init.  Return this if not
   // possible to fold.
-  Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const override;
+  Init *Fold(Record *CurRec) const override;
 
   bool isComplete() const override {
     return LHS->isComplete() && MHS->isComplete() && RHS->isComplete();
index f3f9c67..3bc398f 100644 (file)
@@ -700,7 +700,7 @@ void UnOpInit::Profile(FoldingSetNodeID &ID) const {
   ProfileUnOpInit(ID, getOpcode(), getOperand(), getType());
 }
 
-Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
+Init *UnOpInit::Fold(Record *CurRec) const {
   switch (getOpcode()) {
   case CAST:
     if (isa<StringRecTy>(getType())) {
@@ -714,48 +714,13 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
         return StringInit::get(LHSi->getAsString());
     } else if (isa<RecordRecTy>(getType())) {
       if (StringInit *Name = dyn_cast<StringInit>(LHS)) {
-        // From TGParser::ParseIDValue
-        if (CurRec) {
-          if (const RecordVal *RV = CurRec->getValue(Name)) {
-            if (RV->getType() != getType())
-              PrintFatalError("type mismatch in cast");
-            return VarInit::get(Name, RV->getType());
-          }
-
-          Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name,
-                                              ":");
-
-          if (CurRec->isTemplateArg(TemplateArgName)) {
-            const RecordVal *RV = CurRec->getValue(TemplateArgName);
-            assert(RV && "Template arg doesn't exist??");
-
-            if (RV->getType() != getType())
-              PrintFatalError("type mismatch in cast");
-
-            return VarInit::get(TemplateArgName, RV->getType());
-          }
-        }
-
-        if (CurMultiClass) {
-          Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name,
-                                     "::");
-
-          if (CurMultiClass->Rec.isTemplateArg(MCName)) {
-            const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
-            assert(RV && "Template arg doesn't exist??");
-
-            if (RV->getType() != getType())
-              PrintFatalError("type mismatch in cast");
-
-            return VarInit::get(MCName, RV->getType());
-          }
-        }
         assert(CurRec && "NULL pointer");
         if (Record *D = (CurRec->getRecords()).getDef(Name->getValue()))
           return DefInit::get(D);
 
         PrintFatalError(CurRec->getLoc(),
-                        "Undefined reference:'" + Name->getValue() + "'\n");
+                        Twine("Undefined reference to record: '") +
+                        Name->getValue() + "'\n");
       }
     }
 
@@ -799,8 +764,8 @@ Init *UnOpInit::resolveReferences(Resolver &R) const {
 
   if (LHS != lhs)
     return (UnOpInit::get(getOpcode(), lhs, getType()))
-        ->Fold(R.getCurrentRecord(), nullptr);
-  return Fold(R.getCurrentRecord(), nullptr);
+        ->Fold(R.getCurrentRecord());
+  return Fold(R.getCurrentRecord());
 }
 
 std::string UnOpInit::getAsString() const {
@@ -851,7 +816,7 @@ static StringInit *ConcatStringInits(const StringInit *I0,
   return StringInit::get(Concat);
 }
 
-Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
+Init *BinOpInit::Fold(Record *CurRec) const {
   switch (getOpcode()) {
   case CONCAT: {
     DagInit *LHSs = dyn_cast<DagInit>(LHS);
@@ -974,8 +939,8 @@ Init *BinOpInit::resolveReferences(Resolver &R) const {
 
   if (LHS != lhs || RHS != rhs)
     return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))
-        ->Fold(R.getCurrentRecord(), nullptr);
-  return Fold(R.getCurrentRecord(), nullptr);
+        ->Fold(R.getCurrentRecord());
+  return Fold(R.getCurrentRecord());
 }
 
 std::string BinOpInit::getAsString() const {
@@ -1084,7 +1049,7 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
   return nullptr;
 }
 
-Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
+Init *TernOpInit::Fold(Record *CurRec) const {
   switch (getOpcode()) {
   case SUBST: {
     DefInit *LHSd = dyn_cast<DefInit>(LHS);
@@ -1199,8 +1164,8 @@ Init *TernOpInit::resolveReferences(Resolver &R) const {
 
   if (LHS != lhs || MHS != mhs || RHS != rhs)
     return (TernOpInit::get(getOpcode(), lhs, mhs, rhs, getType()))
-        ->Fold(R.getCurrentRecord(), nullptr);
-  return Fold(R.getCurrentRecord(), nullptr);
+        ->Fold(R.getCurrentRecord());
+  return Fold(R.getCurrentRecord());
 }
 
 std::string TernOpInit::getAsString() const {
@@ -1401,7 +1366,7 @@ Init *TypedInit::getCastTo(RecTy *Ty) const {
     return nullptr;
 
   return UnOpInit::get(UnOpInit::CAST, const_cast<TypedInit *>(this), Ty)
-             ->Fold(nullptr, nullptr);
+      ->Fold(nullptr);
 }
 
 Init *TypedInit::convertInitListSlice(ArrayRef<unsigned> Elements) const {
@@ -2202,7 +2167,7 @@ Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass,
   }
 
   if (BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName))
-    NewName = BinOp->Fold(&CurRec, CurMultiClass);
+    NewName = BinOp->Fold(&CurRec);
   return NewName;
 }
 
index 3bf99e9..4a4a510 100644 (file)
@@ -936,7 +936,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
       return nullptr;
     }
     Lex.Lex();  // eat the ')'
-    return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec, CurMultiClass);
+    return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec);
   }
 
   case tgtok::XIsA: {
@@ -1124,15 +1124,14 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
         Code == BinOpInit::AND || Code == BinOpInit::OR) {
       while (InitList.size() > 2) {
         Init *RHS = InitList.pop_back_val();
-        RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))
-                           ->Fold(CurRec, CurMultiClass);
+        RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))->Fold(CurRec);
         InitList.back() = RHS;
       }
     }
 
     if (InitList.size() == 2)
       return (BinOpInit::get(Code, InitList[0], InitList[1], Type))
-        ->Fold(CurRec, CurMultiClass);
+          ->Fold(CurRec);
 
     Error(OpLoc, "expected two operands to operator");
     return nullptr;
@@ -1237,7 +1236,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
     }
 
     return (TernOpInit::get(TernOpInit::FOREACH, LHS, MHS, RHS, OutType))
-               ->Fold(CurRec, CurMultiClass);
+        ->Fold(CurRec);
   }
 
   case tgtok::XDag:
@@ -1378,8 +1377,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
       break;
     }
     }
-    return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec,
-                                                             CurMultiClass);
+    return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);
   }
 
   case tgtok::XFoldl: {
@@ -1996,8 +1994,9 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
         break;
       }
 
-      Result = BinOpInit::get(BinOpInit::STRCONCAT, LHS, RHS,
-                              StringRecTy::get())->Fold(CurRec, CurMultiClass);
+      Result =
+          BinOpInit::get(BinOpInit::STRCONCAT, LHS, RHS, StringRecTy::get())
+              ->Fold(CurRec);
       break;
     }
   }
@@ -2832,11 +2831,12 @@ Record *TGParser::InstantiateMulticlassDef(MultiClass &MC, Record *DefProto,
   if (DefNameString) {
     // We have a fully expanded string so there are no operators to
     // resolve.  We should concatenate the given prefix and name.
-    DefName =
-      BinOpInit::get(BinOpInit::STRCONCAT,
-                     UnOpInit::get(UnOpInit::CAST, DefmPrefix,
-                                   StringRecTy::get())->Fold(DefProto, &MC),
-                     DefName, StringRecTy::get())->Fold(DefProto, &MC);
+    DefName = BinOpInit::get(
+                  BinOpInit::STRCONCAT,
+                  UnOpInit::get(UnOpInit::CAST, DefmPrefix, StringRecTy::get())
+                      ->Fold(DefProto),
+                  DefName, StringRecTy::get())
+                  ->Fold(DefProto);
   }
 
   // Make a trail of SMLocs from the multiclass instantiations.
index 6642d33..2f399e5 100644 (file)
@@ -12,7 +12,7 @@ class B<A a> {
 multiclass M0<string s> {
   // This should work fine.
   def _m00 : B<!cast<A>(s)>;
-  // CHECK: error: Undefined reference:'d1_r1_no_such_record'
+  // CHECK: error: Undefined reference to record: 'd1_r1_no_such_record'
   def _m01: B<!cast<A>(s#"_no_such_record")>;
 }