I'd like to check that some "memory location" is annotated with {.volatile.}, 
to make sure my code only compiles, if I use {.volatile.} in the right place. I 
searc the lib code but didn't really find much, except this (asyncmacro.nim):
    
    
    proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
      # ...
      # LINE NO: 385
      # If proc has an explicit gcsafe pragma, we add it to iterator as well.
      if prc.pragma.findChild(it.kind in {nnkSym, nnkIdent} and $it == 
"gcsafe") != nil:
        closureIterator.addPragma(newIdentNode("gcsafe"))
    

I gave it a try, but did not get very far, as I'm still "practicing" the 
language itself, and haven't learned (or more precisely already forgot), how 
the meta-programming works.

Here is what I tried: 
    
    
    import macros, strutils
    
    type
      VolatilePtr*[T] = distinct ptr T
      # Means it's a pointer to some volatile value
    
    proc hasAnnotation(stuff: NimNode, annotation: static[string]): bool 
{.compileTime.} =
      (stuff.pragma.findChild(it.kind in {nnkSym, nnkIdent} and $it == 
annotation) != nil)
    
    template toVolatilePtr*[T](t: untyped) =
      when hasAnnotation(t, "volatile"):
        VolatilePtr[T](addr t)
      else:
        {.error: "t is not volatile!".}
    
    
    when isMainModule:
      var tua = 42'i32
      let p: VolatilePtr[int32] = toVolatilePtr[int32](tua)
      let tua2: int32 = 42'i32 #atomicLoadNSeqCST[int32](p)
      assert(tua2 == tua)
    

Reply via email to