summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2014-04-09 00:05:59 +0200
committerAndreas Rumpf <rumpf_a@web.de>2014-04-09 00:05:59 +0200
commite2d02d59432e827e836992e56c7088917ea94e19 (patch)
tree16a47cc4b3d9d5e6c00b32b6ee335322065253d2
parent35efec457c9c48eaa3ff2ef9cdb74a0d0912fc60 (diff)
parent68b7779bc7582ceb0bce0fd8fa79a91c17498b2d (diff)
downloadNim-e2d02d59432e827e836992e56c7088917ea94e19.tar.gz
Merge pull request #691 from rbehrends/fix-shallow-pragma
Fixes shallow pragma for objects and tuples.
-rw-r--r--compiler/ccgexprs.nim46
1 files changed, 39 insertions, 7 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 873c61ed4..daa0c8d88 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -212,22 +212,36 @@ proc optAsgnLoc(a: TLoc, t: PType, field: PRope): TLoc =
   result.heapRoot = a.heapRoot
 
 proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
+  let newflags =
+    if src.k == locData:
+      flags + { needToCopy }
+    elif tfShallow in dest.t.flags:
+      flags - { needToCopy }
+    else:
+      flags
   for i in 0 .. <dest.t.len:
     let t = dest.t.sons[i]
     let field = ropef("Field$1", i.toRope)
     genAssignment(p, optAsgnLoc(dest, t, field), 
-                     optAsgnLoc(src, t, field), flags)
+                     optAsgnLoc(src, t, field), newflags)
 
 proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags,
                       t: PNode) =
   if t == nil: return
+  let newflags =
+    if src.k == locData:
+      flags + { needToCopy }
+    elif tfShallow in dest.t.flags:
+      flags - { needToCopy }
+    else:
+      flags
   case t.kind
   of nkSym:
     let field = t.sym
     genAssignment(p, optAsgnLoc(dest, field.typ, field.loc.r), 
-                     optAsgnLoc(src, field.typ, field.loc.r), flags)
+                     optAsgnLoc(src, field.typ, field.loc.r), newflags)
   of nkRecList:
-    for child in items(t): genOptAsgnObject(p, dest, src, flags, child)
+    for child in items(t): genOptAsgnObject(p, dest, src, newflags, child)
   else: nil
 
 proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
@@ -264,13 +278,13 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
   of tyRef:
     genRefAssign(p, dest, src, flags)
   of tySequence:
-    if needToCopy notin flags:
+    if needToCopy notin flags and src.k != locData:
       genRefAssign(p, dest, src, flags)
     else:
       linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
               addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t))
   of tyString:
-    if needToCopy notin flags:
+    if needToCopy notin flags and src.k != locData:
       genRefAssign(p, dest, src, flags)
     else:
       if dest.s == OnStack or not usesNativeGC():
@@ -355,6 +369,22 @@ proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc) =
   else:
     d = s # ``d`` is free, so fill it with ``s``
 
+proc putDataIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) =
+  var a: TLoc
+  if d.k != locNone:
+    # need to generate an assignment here
+    initLoc(a, locData, getUniqueType(t), OnUnknown)
+    a.r = r
+    if lfNoDeepCopy in d.flags: genAssignment(p, d, a, {})
+    else: genAssignment(p, d, a, {needToCopy})
+  else:
+    # we cannot call initLoc() here as that would overwrite
+    # the flags field!
+    d.k = locData
+    d.t = getUniqueType(t)
+    d.r = r
+    d.a = -1
+
 proc putIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) =
   var a: TLoc
   if d.k != locNone:
@@ -1772,7 +1802,7 @@ proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
   if d.k == locNone:
     fillLoc(d, locData, t, tmp, OnHeap)
   else:
-    putIntoDest(p, d, t, tmp)
+    putDataIntoDest(p, d, t, tmp)
 
 proc expr(p: BProc, n: PNode, d: var TLoc) =
   case n.kind
@@ -1826,7 +1856,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
   of nkNilLit:
     if not isEmptyType(n.typ):
       putIntoDest(p, d, n.typ, genLiteral(p, n))
-  of nkStrLit..nkTripleStrLit, nkIntLit..nkUInt64Lit,
+  of nkStrLit..nkTripleStrLit:
+    putDataIntoDest(p, d, n.typ, genLiteral(p, n))
+  of nkIntLit..nkUInt64Lit,
      nkFloatLit..nkFloat128Lit, nkCharLit:
     putIntoDest(p, d, n.typ, genLiteral(p, n))
   of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkPostfix, nkCommand,