Generalize getFieldType to work on all TypedInits. Add a couple of testcases from
authorDavid Greene <greened@obbligato.org>
Fri, 3 Sep 2010 21:00:49 +0000 (21:00 +0000)
committerDavid Greene <greened@obbligato.org>
Fri, 3 Sep 2010 21:00:49 +0000 (21:00 +0000)
Amaury Pouly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113010 91177308-0d34-0410-b5e6-96231b3b80d8

test/TableGen/FieldAccess.td [new file with mode: 0644]
test/TableGen/ListManip.td [new file with mode: 0644]
utils/TableGen/Record.cpp
utils/TableGen/Record.h

diff --git a/test/TableGen/FieldAccess.td b/test/TableGen/FieldAccess.td
new file mode 100644 (file)
index 0000000..ad652e7
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: tblgen %s
+class Bla<string t>
+{
+  string blu = t;
+}
+
+class Bli<Bla t>
+{
+  Bla bla = t;
+}
+
+def a : Bli<Bla<"">>;
+def b : Bla<!cast<Bla>(a.bla).blu>; // works
+def c : Bla<a.bla.blu>; // doesn't work: Cannot access field 'blu' of value 'a.bla'
diff --git a/test/TableGen/ListManip.td b/test/TableGen/ListManip.td
new file mode 100644 (file)
index 0000000..c221bb1
--- /dev/null
@@ -0,0 +1,10 @@
+// RUN: tblgen %s
+class Bli<string _t>
+{
+  string t = _t;
+}
+
+class Bla<list<Bli> _bli>
+: Bli<!car(_bli).t>
+{
+}
index d2cf379907f64465338f58998f9b9d3ffd787ec2..dc793586fbeef1ce30b93ff9d12c2b2eb4930c55 100644 (file)
@@ -628,23 +628,6 @@ std::string UnOpInit::getAsString() const {
   return Result + "(" + LHS->getAsString() + ")";
 }
 
-RecTy *UnOpInit::getFieldType(const std::string &FieldName) const {
-  switch (getOpcode()) {
-  default: assert(0 && "Unknown unop");
-  case CAST: {
-    RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType());
-    if (RecordType) {
-      RecordVal *Field = RecordType->getRecord()->getValue(FieldName);
-      if (Field) {
-        return Field->getType();
-      }
-    }
-    break;
-  }
-  }
-  return 0;
-}
-
 Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
   switch (getOpcode()) {
   default: assert(0 && "Unknown binop");
@@ -1046,6 +1029,17 @@ std::string TernOpInit::getAsString() const {
     + RHS->getAsString() + ")";
 }
 
+RecTy *TypedInit::getFieldType(const std::string &FieldName) const {
+  RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType());
+  if (RecordType) {
+    RecordVal *Field = RecordType->getRecord()->getValue(FieldName);
+    if (Field) {
+      return Field->getType();
+    }
+  }
+  return 0;
+}
+
 Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
   BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
   if (T == 0) return 0;  // Cannot subscript a non-bits variable...
index 8f9fd950bb0fc270508ee7e1ac9367001ef746e8..d6f37eec749ebe16d23337b53035c95f22c6d0af 100644 (file)
@@ -535,6 +535,12 @@ public:
   virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
   virtual Init *convertInitListSlice(const std::vector<unsigned> &Elements);
 
+  /// getFieldType - This method is used to implement the FieldInit class.
+  /// Implementors of this method should return the type of the named field if
+  /// they are of record type.
+  ///
+  virtual RecTy *getFieldType(const std::string &FieldName) const;
+
   /// resolveBitReference - This method is used to implement
   /// VarBitInit::resolveReferences.  If the bit is able to be resolved, we
   /// simply return the resolved value, otherwise we return null.
@@ -835,12 +841,6 @@ public:
 
   virtual Init *resolveReferences(Record &R, const RecordVal *RV);
 
-  /// getFieldType - This method is used to implement the FieldInit class.
-  /// Implementors of this method should return the type of the named field if
-  /// they are of record type.
-  ///
-  virtual RecTy *getFieldType(const std::string &FieldName) const;
-
   virtual std::string getAsString() const;
 };