summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim9
-rw-r--r--compiler/ccgexprs.nim5
-rw-r--r--compiler/evaltempl.nim7
-rw-r--r--compiler/pragmas.nim13
-rw-r--r--compiler/semmagic.nim14
-rw-r--r--compiler/semtempl.nim4
-rw-r--r--compiler/suggest.nim2
7 files changed, 40 insertions, 14 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 3146722cb..fbe6132b3 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -271,6 +271,10 @@ type
                       # language; for interfacing with Objective C
     sfDiscardable,    # returned value may be discarded implicitly
     sfOverriden,      # proc is overriden
+    sfCallSideLineinfo# A flag for template symbols to tell the
+                      # compiler it should use line information from
+                      # the calling side of the macro, not from the
+                      # implementation.
     sfGenSym          # symbol is 'gensym'ed; do not add to symbol table
 
   TSymFlags* = set[TSymFlag]
@@ -1265,7 +1269,10 @@ proc `$`*(x: TLockLevel): string =
   else: result = $int16(x)
 
 proc `$`*(s: PSym): string =
-  result = s.name.s & "@" & $s.id
+  if s != nil:
+    result = s.name.s & "@" & $s.id
+  else:
+    result = "<nil>"
 
 proc newType*(kind: TTypeKind, owner: PSym): PType =
   new(result)
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index fb2fd89a3..8ccca9813 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1997,6 +1997,11 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mSizeOf:
     let t = e.sons[1].typ.skipTypes({tyTypeDesc})
     putIntoDest(p, d, e, "((NI)sizeof($1))" % [getTypeDesc(p.module, t)])
+  of mAlignOf:
+    let t = e.sons[1].typ.skipTypes({tyTypeDesc})
+    if not p.module.compileToCpp:
+      p.module.includeHeader("<stdalign.h>")
+    putIntoDest(p, d, e, "((NI)alignof($1))" % [getTypeDesc(p.module, t)])
   of mChr: genSomeCast(p, e, d)
   of mOrd: genOrd(p, e, d)
   of mLengthArray, mHigh, mLengthStr, mLengthSeq, mLengthOpenArray:
diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim
index 0f9220102..43c038270 100644
--- a/compiler/evaltempl.nim
+++ b/compiler/evaltempl.nim
@@ -186,9 +186,9 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
                   renderTree(result, {renderNoComments}))
   else:
     result = copyNode(body)
-    #ctx.instLines = body.kind notin {nkStmtList, nkStmtListExpr,
-    #                                 nkBlockStmt, nkBlockExpr}
-    #if ctx.instLines: result.info = n.info
+    ctx.instLines = sfCallSideLineinfo in tmpl.flags
+    if ctx.instLines:
+      result.info = n.info
     for i in countup(0, safeLen(body) - 1):
       evalTemplateAux(body.sons[i], args, ctx, result)
   result.flags.incl nfFromTemplate
@@ -196,4 +196,3 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
   #if ctx.debugActive:
   #  echo "instantion of ", renderTree(result, {renderIds})
   dec(conf.evalTemplateCounter)
-
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index fd721e1e5..b1063b682 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -803,12 +803,15 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
       of wSize:
         if sym.typ == nil: invalidPragma(c, it)
         var size = expectIntLit(c, it)
-        if not isPowerOfTwo(size) or size <= 0 or size > 8:
-          localError(c.config, it.info, "size may only be 1, 2, 4 or 8")
-        else:
+        case size
+        of 1, 2, 4, 8:
           sym.typ.size = size
-          # TODO, this is not correct
-          sym.typ.align = int16(size)
+          if size == 8 and c.config.target.targetCPU == cpuI386:
+            sym.typ.align = 4
+          else:
+            sym.typ.align = int16(size)
+        else:
+          localError(c.config, it.info, "size may only be 1, 2, 4 or 8")
       of wNodecl:
         noVal(c, it)
         incl(sym.loc.flags, lfNoDecl)
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index 6e5563d69..77286393e 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -353,9 +353,17 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
       localError(c.config, n.info, "cannot evaluate 'sizeof' because its type is not defined completely, type: " & n[1].typ.typeToString)
       result = n
   of mAlignOf:
-    result = newIntNode(nkIntLit, getAlign(c.config, n[1].typ))
-    result.info = n.info
-    result.typ = n.typ
+    # this is 100% analog to mSizeOf, could be made more dry.
+    let align = getAlign(c.config, n[1].typ)
+    if align == szUnknownSize:
+      result = n
+    elif align >= 0:
+      result = newIntNode(nkIntLit, align)
+      result.info = n.info
+      result.typ = n.typ
+    else:
+      localError(c.config, n.info, "cannot evaluate 'alignof' because its type is not defined completely, type: " & n[1].typ.typeToString)
+      result = n
   of mOffsetOf:
     var dotExpr: PNode
 
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index d920a54b8..f180b5373 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -558,6 +558,10 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
     incl(s.flags, sfGlobal)
   else:
     s = semIdentVis(c, skTemplate, n.sons[0], {})
+
+  if s.owner != nil and s.owner.name.s == "system" and s.name.s in ["!=", ">=", ">", "incl", "excl", "in", "notin", "isnot"]:
+    incl(s.flags, sfCallSideLineinfo)
+
   styleCheckDef(c.config, s)
   onDef(n[0].info, s)
   # check parameter list:
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index 70a085bdf..d501acd46 100644
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -495,7 +495,7 @@ proc suggestSym*(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym;
 proc extractPragma(s: PSym): PNode =
   if s.kind in routineKinds:
     result = s.ast[pragmasPos]
-  elif s.kind in {skType, skVar, skLet}:
+  elif s.kind in {skType, skVar, skLet} and s.ast[0].kind == nkPragmaExpr:
     # s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma]
     result = s.ast[0][1]
   doAssert result == nil or result.kind == nkPragma