From ea44af954657f743c45fbc45125e197ac3aadd20 Mon Sep 17 00:00:00 2001 From: mergify[bot] Date: Sat, 18 Jun 2022 00:08:41 +0000 Subject: 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 --- .../chisel3/internal/plugin/BundleComponent.scala | 6 +++++- src/test/scala/chiselTests/AutoClonetypeSpec.scala | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) 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. 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) + } } -- cgit v1.2.3