summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/vm.nim20
-rw-r--r--compiler/vmgen.nim4
-rw-r--r--lib/core/macros.nim4
-rw-r--r--tests/macros/tmsginfo.nim24
4 files changed, 40 insertions, 12 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim
index fcbd97b8d..827185737 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -81,14 +81,16 @@ proc stackTraceAux(c: PCtx; x: PStackFrame; pc: int; recursionLimit=100) =
     msgWriteln(c.config, s)
 
 proc stackTrace(c: PCtx, tos: PStackFrame, pc: int,
-                msg: string, n: PNode = nil) =
+                msg: string, lineInfo: TLineInfo) =
   msgWriteln(c.config, "stack trace: (most recent call last)")
   stackTraceAux(c, tos, pc)
   # XXX test if we want 'globalError' for every mode
-  let lineInfo = if n == nil: c.debug[pc] else: n.info
   if c.mode == emRepl: globalError(c.config, lineInfo, msg)
   else: localError(c.config, lineInfo, msg)
 
+proc stackTrace(c: PCtx, tos: PStackFrame, pc: int, msg: string) =
+  stackTrace(c, tos, pc, msg, c.debug[pc])
+
 proc bailOut(c: PCtx; tos: PStackFrame) =
   stackTrace(c, tos, c.exceptionInstr, "unhandled exception: " &
              c.currentExceptionA.sons[3].skipColon.strVal)
@@ -1385,15 +1387,17 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
                                       c.debug[pc], c.config)[0]
       else:
         globalError(c.config, c.debug[pc], "VM is not built with 'gorge' support")
-    of opcNError:
+    of opcNError, opcNWarning, opcNHint:
       decodeB(rkNode)
       let a = regs[ra].node
       let b = regs[rb].node
-      stackTrace(c, tos, pc, a.strVal, if b.kind == nkNilLit: nil else: b)
-    of opcNWarning:
-      message(c.config, c.debug[pc], warnUser, regs[ra].node.strVal)
-    of opcNHint:
-      message(c.config, c.debug[pc], hintUser, regs[ra].node.strVal)
+      let info = if b.kind == nkNilLit: c.debug[pc] else: b.info
+      if instr.opcode == opcNError:
+        stackTrace(c, tos, pc, a.strVal, info)
+      elif instr.opcode == opcNWarning:
+        message(c.config, info, warnUser, a.strVal)
+      elif instr.opcode == opcNHint:
+        message(c.config, info, hintUser, a.strVal)
     of opcParseExprToAst:
       decodeB(rkNode)
       # c.debug[pc].line.int - countLines(regs[rb].strVal) ?
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index a36f559ca..cb4603164 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -1192,10 +1192,10 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
     else: internalAssert c.config, false
   of mNHint:
     unused(c, n, dest)
-    genUnaryStmt(c, n, opcNHint)
+    genBinaryStmt(c, n, opcNHint)
   of mNWarning:
     unused(c, n, dest)
-    genUnaryStmt(c, n, opcNWarning)
+    genBinaryStmt(c, n, opcNWarning)
   of mNError:
     if n.len <= 1:
       # query error condition:
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index bac9ce7a2..5b29d5e94 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -336,10 +336,10 @@ proc copyNimTree*(n: NimNode): NimNode {.magic: "NCopyNimTree", noSideEffect.}
 proc error*(msg: string, n: NimNode = nil) {.magic: "NError", benign.}
   ## writes an error message at compile time
 
-proc warning*(msg: string) {.magic: "NWarning", benign.}
+proc warning*(msg: string, n: NimNode = nil) {.magic: "NWarning", benign.}
   ## writes a warning message at compile time
 
-proc hint*(msg: string) {.magic: "NHint", benign.}
+proc hint*(msg: string, n: NimNode = nil) {.magic: "NHint", benign.}
   ## writes a hint message at compile time
 
 proc newStrLitNode*(s: string): NimNode {.compileTime, noSideEffect.} =
diff --git a/tests/macros/tmsginfo.nim b/tests/macros/tmsginfo.nim
new file mode 100644
index 000000000..bf6c9d537
--- /dev/null
+++ b/tests/macros/tmsginfo.nim
@@ -0,0 +1,24 @@
+discard """
+  nimout: '''tmsginfo.nim(21, 1) Warning: foo1 [User]
+tmsginfo.nim(22, 11) template/generic instantiation from here
+tmsginfo.nim(15, 10) Warning: foo2 [User]
+tmsginfo.nim(23, 1) Hint: foo3 [User]
+tmsginfo.nim(19, 7) Hint: foo4 [User]
+'''
+"""
+
+import macros
+
+macro foo1(y: untyped): untyped =
+  warning("foo1", y)
+macro foo2(y: untyped): untyped =
+  warning("foo2")
+macro foo3(y: untyped): untyped =
+  hint("foo3", y)
+macro foo4(y: untyped): untyped =
+  hint("foo4")
+
+proc x1() {.foo1.} = discard
+proc x2() {.foo2.} = discard
+proc x3() {.foo3.} = discard
+proc x4() {.foo4.} = discard