From c282515b1bcf49f2566390fd059601734ffba196 Mon Sep 17 00:00:00 2001 From: Hasan Genc Date: Mon, 24 Jun 2019 15:04:10 -0700 Subject: Changed Value macro in ChiselEnum so that it doesn't use deprecated (#1104) function. This also fixes prior issue where ChiselEnums would not compile when @chiselName was applied to a module containing a ChiselEnum--- .../src/main/scala/chisel3/StrongEnum.scala | 40 ++++++++++------------ 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'chiselFrontend') diff --git a/chiselFrontend/src/main/scala/chisel3/StrongEnum.scala b/chiselFrontend/src/main/scala/chisel3/StrongEnum.scala index b37ba703..8edce4d8 100644 --- a/chiselFrontend/src/main/scala/chisel3/StrongEnum.scala +++ b/chiselFrontend/src/main/scala/chisel3/StrongEnum.scala @@ -249,14 +249,13 @@ abstract class EnumFactory { protected def Value: Type = macro EnumMacros.ValImpl // scalastyle:off method.name protected def Value(id: UInt): Type = macro EnumMacros.ValCustomImpl // scalastyle:off method.name - protected def do_Value(names: Seq[String]): Type = { + protected def do_Value(name: String): Type = { val result = new Type // We have to use UnknownWidth here, because we don't actually know what the final width will be result.bindToLiteral(id, UnknownWidth()) - val result_name = names.find(!enumNames.contains(_)).get - enum_records.append(EnumRecord(result, result_name)) + enum_records.append(EnumRecord(result, name)) width = (1 max id.bitLength).W id += 1 @@ -264,7 +263,7 @@ abstract class EnumFactory { result } - protected def do_Value(names: Seq[String], id: UInt): Type = { + protected def do_Value(name: String, id: UInt): Type = { // TODO: These throw ExceptionInInitializerError which can be confusing to the user. Get rid of the error, and just // throw an exception if (id.litOption.isEmpty) { @@ -275,7 +274,7 @@ abstract class EnumFactory { } this.id = id.litValue() - do_Value(names) + do_Value(name) } def apply(): Type = new Type @@ -308,31 +307,30 @@ abstract class EnumFactory { private[chisel3] object EnumMacros { def ValImpl(c: Context) : c.Tree = { // scalastyle:off method.name import c.universe._ - val names = getNames(c) - q"""this.do_Value(Seq(..$names))""" - } - def ValCustomImpl(c: Context)(id: c.Expr[UInt]): c.universe.Tree = { // scalastyle:off method.name - import c.universe._ - val names = getNames(c) - q"""this.do_Value(Seq(..$names), $id)""" + // Much thanks to michael_s for this solution: + // stackoverflow.com/questions/18450203/retrieve-the-name-of-the-value-a-scala-macro-invocation-will-be-assigned-to + val term = c.internal.enclosingOwner + val name = term.name.decodedName.toString.trim + + if (name.contains(" ")) { + c.abort(c.enclosingPosition, "Value cannot be called without assigning to an enum") + } + + q"""this.do_Value($name)""" } - // Much thanks to Travis Brown for this solution: - // stackoverflow.com/questions/18450203/retrieve-the-name-of-the-value-a-scala-macro-invocation-will-be-assigned-to - def getNames(c: Context): Seq[String] = { + def ValCustomImpl(c: Context)(id: c.Expr[UInt]): c.universe.Tree = { // scalastyle:off method.name import c.universe._ - val names = c.enclosingClass.collect { - case ValDef(_, name, _, rhs) - if rhs.pos == c.macroApplication.pos => name.decodedName.toString - } + val term = c.internal.enclosingOwner + val name = term.name.decodedName.toString.trim - if (names.isEmpty) { + if (name.contains(" ")) { c.abort(c.enclosingPosition, "Value cannot be called without assigning to an enum") } - names + q"""this.do_Value($name, $id)""" } } -- cgit v1.2.3