summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/scala/chisel3')
-rw-r--r--core/src/main/scala/chisel3/experimental/Analog.scala2
-rw-r--r--core/src/main/scala/chisel3/internal/Error.scala77
2 files changed, 75 insertions, 4 deletions
diff --git a/core/src/main/scala/chisel3/experimental/Analog.scala b/core/src/main/scala/chisel3/experimental/Analog.scala
index 2ce2c86d..6cca81f5 100644
--- a/core/src/main/scala/chisel3/experimental/Analog.scala
+++ b/core/src/main/scala/chisel3/experimental/Analog.scala
@@ -56,6 +56,7 @@ final class Analog private (private[chisel3] val width: Width) extends Element {
case ChildBinding(parent) => parent.topBinding
// See https://github.com/freechipsproject/chisel3/pull/946
case SampleElementBinding(parent) => parent.topBinding
+ case a: MemTypeBinding[_] => a
}
targetTopBinding match {
@@ -83,4 +84,3 @@ final class Analog private (private[chisel3] val width: Width) extends Element {
object Analog {
def apply(width: Width): Analog = new Analog(width)
}
-
diff --git a/core/src/main/scala/chisel3/internal/Error.scala b/core/src/main/scala/chisel3/internal/Error.scala
index 60bb6e2b..134f4c87 100644
--- a/core/src/main/scala/chisel3/internal/Error.scala
+++ b/core/src/main/scala/chisel3/internal/Error.scala
@@ -5,12 +5,82 @@ package chisel3.internal
import scala.annotation.tailrec
import scala.collection.mutable.{ArrayBuffer, LinkedHashMap}
-class ChiselException(message: String, cause: Throwable = null) extends Exception(message, cause) {
+object ExceptionHelpers {
+
+ /** Root packages that are not typically relevant to Chisel user code. */
+ final val packageTrimlist: Set[String] = Set("chisel3", "scala", "java", "jdk", "sun", "sbt")
+
+ /** The object name of Chisel's internal `Builder`. */
+ final val builderName: String = chisel3.internal.Builder.getClass.getName
+
+ /** Return a stack trace element that looks like `... (someMessage)`.
+ * @param message an optional message to include
+ */
+ def ellipsis(message: Option[String] = None): StackTraceElement =
+ new StackTraceElement("..", " ", message.getOrElse(""), -1)
+
+ /** Utility methods that can be added to exceptions.
+ */
+ implicit class ThrowableHelpers(throwable: Throwable) {
+
+ /** For an exception, mutably trim a stack trace to user code only.
+ *
+ * This does the following actions to the stack trace:
+ *
+ * 1. From the top, remove elements while the (root) package matches the packageTrimlist
+ * 2. Optionally, from the bottom, remove elements until the class matches an anchor
+ * 3. From the anchor (or the bottom), remove elements while the (root) package matches the packageTrimlist
+ *
+ * @param packageTrimlist packages that should be removed from the stack trace
+ * @param anchor an optional class name at which user execution might begin, e.g., a main object
+ * @return nothing as this mutates the exception directly
+ */
+ def trimStackTraceToUserCode(
+ packageTrimlist: Set[String] = packageTrimlist,
+ anchor: Option[String] = Some(builderName)
+ ): Unit = {
+ def inTrimlist(ste: StackTraceElement) = {
+ val packageName = ste.getClassName().takeWhile(_ != '.')
+ packageTrimlist.contains(packageName)
+ }
+
+ // Step 1: Remove elements from the top in the package trimlist
+ ((a: Array[StackTraceElement]) => a.view.dropWhile(inTrimlist))
+ // Step 2: Optionally remove elements from the bottom until the anchor
+ .andThen(_.reverse)
+ .andThen( a =>
+ anchor match {
+ case Some(b) => a.dropWhile(ste => !ste.getClassName.startsWith(b))
+ case None => a
+ }
+ )
+ // Step 3: Remove elements from the bottom in the package trimlist
+ .andThen(_.dropWhile(inTrimlist))
+ // Step 4: Reverse back to the original order
+ .andThen(_.reverse.toArray)
+ // Step 5: Add ellipsis stack trace elements and "--full-stacktrace" info
+ .andThen(a =>
+ ellipsis() +:
+ a :+
+ ellipsis() :+
+ ellipsis(Some("Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace")))
+ // Step 5: Mutate the stack trace in this exception
+ .andThen(throwable.setStackTrace(_))
+ .apply(throwable.getStackTrace)
+ }
+
+ }
+
+}
+
+class ChiselException(message: String, cause: Throwable = null) extends Exception(message, cause, true, true) {
/** Package names whose stack trace elements should be trimmed when generating a trimmed stack trace */
+ @deprecated("Use ExceptionHelpers.packageTrimlist. This will be removed in Chisel 3.6", "3.5")
val blacklistPackages: Set[String] = Set("chisel3", "scala", "java", "sun", "sbt")
/** The object name of Chisel's internal `Builder`. Everything stack trace element after this will be trimmed. */
+ @deprecated("Use ExceptionHelpers.builderName. This will be removed in Chisel 3.6", "3.5")
val builderName: String = chisel3.internal.Builder.getClass.getName
/** Examine a [[Throwable]], to extract all its causes. Innermost cause is first.
@@ -27,7 +97,7 @@ class ChiselException(message: String, cause: Throwable = null) extends Exceptio
/** Returns true if an exception contains */
private def containsBuilder(throwable: Throwable): Boolean =
throwable.getStackTrace().collectFirst {
- case ste if ste.getClassName().startsWith(builderName) => throwable
+ case ste if ste.getClassName().startsWith(ExceptionHelpers.builderName) => throwable
}.isDefined
/** Examine this [[ChiselException]] and it's causes for the first [[Throwable]] that contains a stack trace including
@@ -142,7 +212,8 @@ private[chisel3] class ErrorLog {
}
if (!allErrors.isEmpty) {
- throwException("Fatal errors during hardware elaboration")
+ throw new ChiselException("Fatal errors during hardware elaboration. Look above for error list.")
+ with scala.util.control.NoStackTrace
} else {
// No fatal errors, clear accumulated warnings since they've been reported
errors.clear()