summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormergify[bot]2022-06-18 00:08:41 +0000
committerGitHub2022-06-18 00:08:41 +0000
commitea44af954657f743c45fbc45125e197ac3aadd20 (patch)
tree66bf9e3560c336196e1407694fc08cdac4e6bd5e
parent01100fa9af0e34b9a4ddb87b8060e6e3178d4272 (diff)
Handle varargs constructor arguments in Bundle plugin (#2585) (#2588)
Previously, the plugin would crash with a useless internal error. (cherry picked from commit 9fcfb252beb9f06d8d1409fe7db9c8b3b6b962ce) Co-authored-by: Jack Koenig <koenig@sifive.com>
-rw-r--r--plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala6
-rw-r--r--src/test/scala/chiselTests/AutoClonetypeSpec.scala19
2 files changed, 24 insertions, 1 deletions
diff --git a/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala b/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala
index e3ec0a04..eca3b158 100644
--- a/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala
+++ b/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala
@@ -84,6 +84,8 @@ private[plugin] class BundleComponent(val global: Global, arguments: ChiselPlugi
def isNullaryMethodNamed(name: String, defdef: DefDef): Boolean =
defdef.name.decodedName.toString == name && defdef.tparams.isEmpty && defdef.vparamss.isEmpty
+ def isVarArgs(sym: Symbol): Boolean = definitions.isRepeatedParamType(sym.tpe)
+
def getConstructorAndParams(body: List[Tree]): (Option[DefDef], Seq[Symbol]) = {
val paramAccessors = mutable.ListBuffer[Symbol]()
var primaryConstructor: Option[DefDef] = None
@@ -134,7 +136,9 @@ private[plugin] class BundleComponent(val global: Global, arguments: ChiselPlugi
// Make this.<ref>
val select = gen.mkAttributedSelect(thiz.asInstanceOf[Tree], p)
// Clone any Data parameters to avoid field aliasing, need full clone to include direction
- if (isData(vp.symbol)) cloneTypeFull(select.asInstanceOf[Tree]) else select
+ val cloned = if (isData(vp.symbol)) cloneTypeFull(select.asInstanceOf[Tree]) else select
+ // Need to splat varargs
+ if (isVarArgs(vp.symbol)) q"$cloned: _*" else cloned
})
val tparamList = bundle.tparams.map { t => Ident(t.symbol) }
diff --git a/src/test/scala/chiselTests/AutoClonetypeSpec.scala b/src/test/scala/chiselTests/AutoClonetypeSpec.scala
index 2ab4c800..5d2cd496 100644
--- a/src/test/scala/chiselTests/AutoClonetypeSpec.scala
+++ b/src/test/scala/chiselTests/AutoClonetypeSpec.scala
@@ -381,4 +381,23 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
}
elaborate(new MyModule)
}
+
+ it should "support Bundles with vararg arguments" in {
+ // Without the fix, this doesn't even compile
+ // Extra parameter lists to make this a complex test case
+ class VarArgsBundle(x: Int)(y: Int, widths: Int*) extends Bundle {
+ def mkField(idx: Int): Option[UInt] =
+ (x +: y +: widths).lift(idx).map(w => UInt(w.W))
+ val foo = mkField(0)
+ val bar = mkField(1)
+ val fizz = mkField(2)
+ val buzz = mkField(3)
+ }
+ class MyModule extends Module {
+ val in = IO(Input(new VarArgsBundle(1)(2, 3, 4)))
+ val out = IO(Output(new VarArgsBundle(1)(2, 3, 4)))
+ out := in
+ }
+ elaborate(new MyModule)
+ }
}