summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/test/TableGen/UnsetBitInit.td10
-rw-r--r--llvm/utils/TableGen/Record.cpp28
2 files changed, 30 insertions, 8 deletions
diff --git a/llvm/test/TableGen/UnsetBitInit.td b/llvm/test/TableGen/UnsetBitInit.td
new file mode 100644
index 00000000000..91342ecb966
--- /dev/null
+++ b/llvm/test/TableGen/UnsetBitInit.td
@@ -0,0 +1,10 @@
+// RUN: tblgen %s
+class x {
+ field bits<32> A;
+}
+
+class y<bits<2> B> : x {
+ let A{21-20} = B;
+}
+
+def z : y<{0,?}>;
diff --git a/llvm/utils/TableGen/Record.cpp b/llvm/utils/TableGen/Record.cpp
index 7e84d008e69..fbe120759d3 100644
--- a/llvm/utils/TableGen/Record.cpp
+++ b/llvm/utils/TableGen/Record.cpp
@@ -490,8 +490,11 @@ Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
if (Elt >= getSize())
return 0; // Out of range reference.
Init *E = getElement(Elt);
- if (!dynamic_cast<UnsetInit*>(E)) // If the element is set
- return E; // Replace the VarListElementInit with it.
+ // If the element is set to some value, or if we are resolving a reference
+ // to a specific variable and that variable is explicitly unset, then
+ // replace the VarListElementInit with it.
+ if (IRV || !dynamic_cast<UnsetInit*>(E))
+ return E;
return 0;
}
@@ -1116,8 +1119,11 @@ Init *VarInit::resolveBitReference(Record &R, const RecordVal *IRV,
assert(Bit < BI->getNumBits() && "Bit reference out of range!");
Init *B = BI->getBit(Bit);
- if (!dynamic_cast<UnsetInit*>(B)) // If the bit is not set...
- return B; // Replace the VarBitInit with it.
+ // If the bit is set to some value, or if we are resolving a reference to a
+ // specific variable and that variable is explicitly unset, then replace the
+ // VarBitInit with it.
+ if (IRV || !dynamic_cast<UnsetInit*>(B))
+ return B;
return 0;
}
@@ -1138,8 +1144,11 @@ Init *VarInit::resolveListElementReference(Record &R, const RecordVal *IRV,
if (Elt >= LI->getSize())
return 0; // Out of range reference.
Init *E = LI->getElement(Elt);
- if (!dynamic_cast<UnsetInit*>(E)) // If the element is set
- return E; // Replace the VarListElementInit with it.
+ // If the element is set to some value, or if we are resolving a reference
+ // to a specific variable and that variable is explicitly unset, then
+ // replace the VarListElementInit with it.
+ if (IRV || !dynamic_cast<UnsetInit*>(E))
+ return E;
return 0;
}
@@ -1246,8 +1255,11 @@ Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV,
if (Elt >= LI->getSize()) return 0;
Init *E = LI->getElement(Elt);
- if (!dynamic_cast<UnsetInit*>(E)) // If the bit is set...
- return E; // Replace the VarListElementInit with it.
+ // If the element is set to some value, or if we are resolving a
+ // reference to a specific variable and that variable is explicitly
+ // unset, then replace the VarListElementInit with it.
+ if (RV || !dynamic_cast<UnsetInit*>(E))
+ return E;
}
return 0;
}
OpenPOWER on IntegriCloud