Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/src/main/mima-filters/3.6.0.backwards.excludes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SourceInfo is sealed
ProblemFilters.exclude[ReversedMissingMethodProblem]("chisel3.experimental.SourceInfo.filenameOption")
# ErrorEntry is private
ProblemFilters.exclude[DirectMissingMethodProblem]("chisel3.internal.ErrorEntry.serialize")
8 changes: 5 additions & 3 deletions core/src/main/scala/chisel3/Bits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import chisel3.internal.sourceinfo.{
import chisel3.internal.firrtl.PrimOp._
import _root_.firrtl.{ir => firrtlir}
import _root_.firrtl.{constraint => firrtlconstraint}
import chisel3.internal.{castToInt, Builder}
import chisel3.internal.{castToInt, Builder, Warning, WarningID}

/** Exists to unify common interfaces of [[Bits]] and [[Reset]].
*
Expand Down Expand Up @@ -154,9 +154,11 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi
} else {
x.widthOption.foreach { xWidth =>
if (xWidth >= 31 || (1 << (xWidth - 1)) >= thisWidth) {
Builder.warning(s"Dynamic index with width $xWidth is too large for extractee of width $thisWidth")
val msg = s"Dynamic index with width $xWidth is too large for extractee of width $thisWidth"
Builder.warning(Warning(WarningID.DynamicBitSelectTooWide, msg))
} else if ((1 << xWidth) < thisWidth) {
Builder.warning(s"Dynamic index with width $xWidth is too small for extractee of width $thisWidth")
val msg = s"Dynamic index with width $xWidth is too small for extractee of width $thisWidth"
Builder.warning(Warning(WarningID.DynamicBitSelectTooNarrow, msg))
}
}
}
Expand Down
16 changes: 13 additions & 3 deletions core/src/main/scala/chisel3/ChiselEnum.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,16 @@ import chisel3.internal.Builder.pushOp
import chisel3.internal.firrtl.PrimOp._
import chisel3.internal.firrtl._
import chisel3.internal.sourceinfo._
import chisel3.internal.{throwException, Binding, Builder, BuilderContextCache, ChildBinding, ConstrainedBinding}
import chisel3.internal.{
throwException,
Binding,
Builder,
BuilderContextCache,
ChildBinding,
ConstrainedBinding,
Warning,
WarningID
}

import chisel3.experimental.EnumAnnotations._

Expand Down Expand Up @@ -315,10 +324,11 @@ abstract class ChiselEnum {
} else if (n.getWidth > this.getWidth) {
throwException(s"The UInt being cast to $enumTypeName is wider than $enumTypeName's width ($getWidth)")
} else {
// TODO fold this into warning filters
if (!Builder.suppressEnumCastWarning && warn && !this.isTotal) {
Builder.warning(
val msg =
s"Casting non-literal UInt to $enumTypeName. You can use $enumTypeName.safe to cast without this warning."
)
Builder.warning(Warning(WarningID.UnsafeUIntCastToEnum, msg))
}
val glue = Wire(new UnsafeEnum(width))
glue := n
Expand Down
47 changes: 47 additions & 0 deletions core/src/main/scala/chisel3/experimental/SourceInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@ sealed trait SourceInfo {
* Make a useful message if SourceInfo is available, nothing otherwise
*/
def makeMessage(f: String => String): String

/** The filename for the originating source file, if known */
def filenameOption: Option[String]
}

sealed trait NoSourceInfo extends SourceInfo {
def makeMessage(f: String => String): String = ""
def filenameOption: Option[String] = None
}

/** For when source info can't be generated because of a technical limitation, like for Reg because
Expand All @@ -46,6 +50,49 @@ case object DeprecatedSourceInfo extends NoSourceInfo
*/
case class SourceLine(filename: String, line: Int, col: Int) extends SourceInfo {
def makeMessage(f: String => String): String = f(s"@[$filename $line:$col]")
def filenameOption: Option[String] = Some(filename)
}

/** Source locator with a line but no column, derived from a stack trace
*
* Only used for warning and error reporting when no [[SourceLine]] is available
*/
private[chisel3] case class SourceLineNoCol(filename: String, line: Int) extends SourceInfo {
def makeMessage(f: String => String): String = f(s"@[$filename $line]")
def filenameOption: Option[String] = Some(filename)
}
private[chisel3] object SourceLineNoCol {

/** Returns the best guess at the first stack frame that belongs to user code.
*/
private def getUserLineNumber: Option[StackTraceElement] = {
def isChiselClassname(className: String): Boolean = {
// List of classpath prefixes that are Chisel internals and should be ignored when looking for user code
// utils are not part of internals and errors there can be reported
val chiselPrefixes = Set(
"java.",
"scala.",
"chisel3.",
"chisel3.internal.",
"chisel3.experimental.",
"chisel3.package$" // for some compatibility / deprecated types
)
!chiselPrefixes.filter(className.startsWith(_)).isEmpty
}

Thread
.currentThread()
.getStackTrace
.toList
.dropWhile(
// Get rid of everything in Chisel core
ste => isChiselClassname(ste.getClassName)
)
.headOption
}

def materialize: Option[SourceLineNoCol] =
getUserLineNumber.map { elt => new SourceLineNoCol(elt.getFileName, elt.getLineNumber) }
}

object SourceInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ object Definition extends SourceInfoDoc {
): Definition[T] = {
val dynamicContext = {
val context = Builder.captureContext()
new DynamicContext(Nil, context.throwOnFirstError, context.warningsAsErrors, context.sourceRoots)
new DynamicContext(Nil, context.throwOnFirstError, context.warningFilters, context.sourceRoots)
}
Builder.globalNamespace.copyTo(dynamicContext.globalNamespace)
dynamicContext.inDefinition = true
Expand Down
14 changes: 7 additions & 7 deletions core/src/main/scala/chisel3/internal/Builder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ private[chisel3] class ChiselContext() {
private[chisel3] class DynamicContext(
val annotationSeq: AnnotationSeq,
val throwOnFirstError: Boolean,
val warningsAsErrors: Boolean,
val warningFilters: Seq[WarningFilter],
val sourceRoots: Seq[File]) {
val importDefinitionAnnos = annotationSeq.collect { case a: ImportDefinitionAnnotation[_] => a }

Expand Down Expand Up @@ -487,7 +487,7 @@ private[chisel3] class DynamicContext(
var whenStack: List[WhenContext] = Nil
var currentClock: Option[Clock] = None
var currentReset: Option[Reset] = None
val errors = new ErrorLog(warningsAsErrors, sourceRoots)
val errors = new ErrorLog(warningFilters, sourceRoots, throwOnFirstError)
val namingStack = new NamingStack

// Used to indicate if this is the top-level module of full elaboration, or from a Definition
Expand Down Expand Up @@ -778,16 +778,16 @@ private[chisel3] object Builder extends LazyLogging {
def errors: ErrorLog = dynamicContext.errors
def error(m: => String)(implicit sourceInfo: SourceInfo): Unit = {
// If --throw-on-first-error is requested, throw an exception instead of aggregating errors
if (dynamicContextVar.value.isDefined && !dynamicContextVar.value.get.throwOnFirstError) {
if (dynamicContextVar.value.isDefined) {
errors.error(m, sourceInfo)
} else {
throwException(m)
}
}
def warning(m: => String)(implicit sourceInfo: SourceInfo): Unit =
if (dynamicContextVar.value.isDefined) errors.warning(m, sourceInfo)
def warningNoLoc(m: => String): Unit = if (dynamicContextVar.value.isDefined) errors.warningNoLoc(m)
def deprecated(m: => String, location: Option[String] = None): Unit =
def warning(warning: Warning): Unit =
if (dynamicContextVar.value.isDefined) errors.warning(warning)

def deprecated(m: => String, location: Option[String] = None): Unit =
if (dynamicContextVar.value.isDefined) errors.deprecated(m, location)

/** Record an exception as an error, and throw it.
Expand Down
Loading