add more APIs to compiler/debugutils; re-export it (#18243)
This commit is contained in:
parent
a250481dcd
commit
87cd9b24a3
4 changed files with 85 additions and 0 deletions
|
|
@ -4,7 +4,26 @@ Utilities to help with debugging nim compiler.
|
||||||
Experimental API, subject to change.
|
Experimental API, subject to change.
|
||||||
]##
|
]##
|
||||||
|
|
||||||
|
#[
|
||||||
|
## example
|
||||||
|
useful debugging flags:
|
||||||
|
--stacktrace -d:debug -d:nimDebugUtils
|
||||||
|
nim c -o:bin/nim_temp --stacktrace -d:debug -d:nimDebugUtils compiler/nim
|
||||||
|
|
||||||
|
## future work
|
||||||
|
* expose and improve astalgo.debug, replacing it by std/prettyprints,
|
||||||
|
refs https://github.com/nim-lang/RFCs/issues/385
|
||||||
|
]#
|
||||||
|
|
||||||
import options
|
import options
|
||||||
|
import std/wrapnils
|
||||||
|
export wrapnils
|
||||||
|
# allows using things like: `?.n.sym.typ.len`
|
||||||
|
|
||||||
|
import std/stackframes
|
||||||
|
export stackframes
|
||||||
|
# allows using things like: `setFrameMsg c.config$n.info & " " & $n.kind`
|
||||||
|
# which doesn't log, but augments stacktrace with side channel information
|
||||||
|
|
||||||
var conf0: ConfigRef
|
var conf0: ConfigRef
|
||||||
|
|
||||||
|
|
@ -17,3 +36,21 @@ proc onNewConfigRef*(conf: ConfigRef) {.inline.} =
|
||||||
proc getConfigRef*(): ConfigRef =
|
proc getConfigRef*(): ConfigRef =
|
||||||
## nil, if -d:nimDebugUtils wasn't specified
|
## nil, if -d:nimDebugUtils wasn't specified
|
||||||
result = conf0
|
result = conf0
|
||||||
|
|
||||||
|
proc isCompilerDebug*(): bool =
|
||||||
|
##[
|
||||||
|
Provides a simple way for user code to enable/disable logging in the compiler
|
||||||
|
in a granular way. This can then be used in the compiler as follows:
|
||||||
|
```nim
|
||||||
|
if isCompilerDebug():
|
||||||
|
echo ?.n.sym.typ.len
|
||||||
|
```
|
||||||
|
]##
|
||||||
|
runnableExamples:
|
||||||
|
proc main =
|
||||||
|
echo 2
|
||||||
|
{.define(nimCompilerDebug).}
|
||||||
|
echo 3.5 # code section in which `isCompilerDebug` will be true
|
||||||
|
{.undef(nimCompilerDebug).}
|
||||||
|
echo 'x'
|
||||||
|
conf0.isDefined("nimCompilerDebug")
|
||||||
|
|
|
||||||
|
|
@ -472,7 +472,10 @@ const foreignPackageNotesDefault* = {
|
||||||
proc isDefined*(conf: ConfigRef; symbol: string): bool
|
proc isDefined*(conf: ConfigRef; symbol: string): bool
|
||||||
|
|
||||||
when defined(nimDebugUtils):
|
when defined(nimDebugUtils):
|
||||||
|
# this allows inserting debugging utilties in all modules that import `options`
|
||||||
|
# with a single switch, which is useful when debugging compiler.
|
||||||
import debugutils
|
import debugutils
|
||||||
|
export debugutils
|
||||||
|
|
||||||
proc initConfigRefCommon(conf: ConfigRef) =
|
proc initConfigRefCommon(conf: ConfigRef) =
|
||||||
conf.selectedGC = gcRefc
|
conf.selectedGC = gcRefc
|
||||||
|
|
|
||||||
|
|
@ -2716,6 +2716,13 @@ proc getNilType(c: PContext): PType =
|
||||||
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
when defined(nimCompilerStacktraceHints):
|
when defined(nimCompilerStacktraceHints):
|
||||||
setFrameMsg c.config$n.info & " " & $n.kind
|
setFrameMsg c.config$n.info & " " & $n.kind
|
||||||
|
when false: # see `tdebugutils`
|
||||||
|
if isCompilerDebug():
|
||||||
|
echo (">", c.config$n.info, n, flags, n.kind)
|
||||||
|
defer:
|
||||||
|
if isCompilerDebug():
|
||||||
|
echo ("<", c.config$n.info, n, ?.result.typ)
|
||||||
|
|
||||||
result = n
|
result = n
|
||||||
if c.config.cmd == cmdIdeTools: suggestExpr(c, n)
|
if c.config.cmd == cmdIdeTools: suggestExpr(c, n)
|
||||||
if nfSem in n.flags: return
|
if nfSem in n.flags: return
|
||||||
|
|
|
||||||
38
tests/compiler/tdebugutils.nim
Normal file
38
tests/compiler/tdebugutils.nim
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
discard """
|
||||||
|
joinable: false
|
||||||
|
disabled: true
|
||||||
|
"""
|
||||||
|
|
||||||
|
#[
|
||||||
|
This test illustrates some features of `debugutils` to debug the compiler.
|
||||||
|
|
||||||
|
## example
|
||||||
|
this shows how to enable compiler logging just for a section of user code,
|
||||||
|
without generating tons of unrelated log messages for code you're not interested
|
||||||
|
in debugging.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# enable some debugging code, e.g. the `when false:` block in `semExpr`
|
||||||
|
nim c -o:bin/nim_temp --stacktrace -d:debug -d:nimDebugUtils compiler/nim
|
||||||
|
bin/nim_temp c tests/compiler/tdebugutils.nim
|
||||||
|
```
|
||||||
|
|
||||||
|
(use --filenames:abs for abs files)
|
||||||
|
|
||||||
|
## result
|
||||||
|
("<", "tdebugutils.nim(16, 3)", {.define(nimCompilerDebug).}, nil)
|
||||||
|
(">", "tdebugutils.nim(17, 3)", let a = 2.5 * 3, {}, nkLetSection)
|
||||||
|
(">", "tdebugutils.nim(17, 15)", 2.5 * 3, {efAllowDestructor, efWantValue}, nkInfix)
|
||||||
|
(">", "tdebugutils.nim(17, 11)", 2.5, {efAllowStmt, efDetermineType, efOperand}, nkFloatLit)
|
||||||
|
("<", "tdebugutils.nim(17, 11)", 2.5, float64)
|
||||||
|
(">", "tdebugutils.nim(17, 17)", 3, {efAllowStmt, efDetermineType, efOperand}, nkIntLit)
|
||||||
|
("<", "tdebugutils.nim(17, 17)", 3, int literal(3))
|
||||||
|
("<", "tdebugutils.nim(17, 15)", 2.5 * 3, float)
|
||||||
|
("<", "tdebugutils.nim(17, 3)", let a = 2.5 * 3, nil)
|
||||||
|
(">", "tdebugutils.nim(18, 3)", {.undef(nimCompilerDebug).}, {}, nkPragma)
|
||||||
|
]#
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
{.define(nimCompilerDebug).}
|
||||||
|
let a = 2.5 * 3
|
||||||
|
{.undef(nimCompilerDebug).}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue