summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-02-28 23:37:38 +0100
committerAraq <rumpf_a@web.de>2015-02-28 23:53:52 +0100
commit2808b7f9a5724c59cea012b7de3215a7dd60177a (patch)
treeb51d9353372f7890f71f44c9a2f49750a2aa3930 /compiler
parent4cb9fba335f51c92e724ff5208eb60ad5ea24b7e (diff)
downloadNim-2808b7f9a5724c59cea012b7de3215a7dd60177a.tar.gz
fixes #2233
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ccgtypes.nim148
1 files changed, 80 insertions, 68 deletions
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 0220d2066..9a5a3ab34 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -226,71 +226,8 @@ proc fillResult(param: PSym) =
     incl(param.loc.flags, lfIndirect)
     param.loc.s = OnUnknown
 
-proc getParamTypeDesc(m: BModule, t: PType, check: var IntSet): PRope =
-  when false:
-    if t.Kind in {tyRef, tyPtr, tyVar}:
-      var b = skipTypes(t.lastson, typedescInst)
-      if b.kind == tySet and mapSetType(b) == ctArray:
-        return getTypeDescAux(m, b, check)
-  result = getTypeDescAux(m, t, check)
-
-proc paramStorageLoc(param: PSym): TStorageLoc =
-  if param.typ.skipTypes({tyVar, tyTypeDesc}).kind notin {tyArray, tyOpenArray}:
-    result = OnStack
-  else:
-    result = OnUnknown
-
-proc genProcParams(m: BModule, t: PType, rettype, params: var PRope, 
-                   check: var IntSet, declareEnvironment=true) = 
-  params = nil
-  if (t.sons[0] == nil) or isInvalidReturnType(t.sons[0]): 
-    rettype = ~"void"
-  else: 
-    rettype = getTypeDescAux(m, t.sons[0], check)
-  for i in countup(1, sonsLen(t.n) - 1): 
-    if t.n.sons[i].kind != nkSym: internalError(t.n.info, "genProcParams")
-    var param = t.n.sons[i].sym
-    if isCompileTimeOnly(param.typ): continue
-    if params != nil: app(params, ~", ")
-    fillLoc(param.loc, locParam, param.typ, mangleName(param),
-            param.paramStorageLoc)
-    app(params, getParamTypeDesc(m, param.typ, check))
-    if ccgIntroducedPtr(param): 
-      app(params, ~"*")
-      incl(param.loc.flags, lfIndirect)
-      param.loc.s = OnUnknown
-    app(params, ~" ")
-    app(params, param.loc.r)
-    # declare the len field for open arrays:
-    var arr = param.typ
-    if arr.kind == tyVar: arr = arr.sons[0]
-    var j = 0
-    while arr.kind in {tyOpenArray, tyVarargs}:
-      # this fixes the 'sort' bug:
-      if param.typ.kind == tyVar: param.loc.s = OnUnknown
-      # need to pass hidden parameter:
-      appf(params, ", NI $1Len$2", [param.loc.r, j.toRope])
-      inc(j)
-      arr = arr.sons[0]
-  if (t.sons[0] != nil) and isInvalidReturnType(t.sons[0]):
-    var arr = t.sons[0]
-    if params != nil: app(params, ", ")
-    app(params, getTypeDescAux(m, arr, check))
-    if (mapReturnType(t.sons[0]) != ctArray):
-      app(params, "*")
-    appf(params, " Result", [])
-  if t.callConv == ccClosure and declareEnvironment: 
-    if params != nil: app(params, ", ")
-    app(params, "void* ClEnv")
-  if tfVarargs in t.flags: 
-    if params != nil: app(params, ", ")
-    app(params, "...")
-  if params == nil: app(params, "void)")
-  else: app(params, ")")
-  params = con("(", params)
-
 proc typeNameOrLiteral(t: PType, literal: string): PRope = 
-  if (t.sym != nil) and (sfImportc in t.sym.flags) and (t.sym.magic == mNone): 
+  if t.sym != nil and sfImportc in t.sym.flags and t.sym.magic == mNone: 
     result = getTypeName(t)
   else: 
     result = toRope(literal)
@@ -327,7 +264,10 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): PRope =
     result = typeNameOrLiteral(typ, NumericalTypeToStr[typ.kind])
   of tyDistinct, tyRange, tyOrdinal: result = getSimpleTypeDesc(m, typ.sons[0])
   else: result = nil
-  
+
+proc pushType(m: BModule, typ: PType) = 
+  add(m.typeStack, typ)
+
 proc getTypePre(m: BModule, typ: PType): PRope = 
   if typ == nil: result = toRope("void")
   else: 
@@ -354,6 +294,81 @@ proc getTypeForward(m: BModule, typ: PType): PRope =
           [structOrUnion(typ), result])
     idTablePut(m.forwTypeCache, typ, result)
   else: internalError("getTypeForward(" & $typ.kind & ')')
+
+proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet): PRope =
+  ## like getTypeDescAux but creates only a *weak* dependency. In other words
+  ## we know we only need a pointer to it so we only generate a struct forward
+  ## declaration:
+  var etB = t.skipTypes(abstractInst)
+  case etB.kind
+  of tyObject, tyTuple:
+    if isImportedCppType(etB) and t.kind == tyGenericInst:
+      result = getTypeDescAux(m, t, check)
+    else:
+      let x = getUniqueType(etB)
+      result = getTypeForward(m, x)
+      pushType(m, x)
+  else:
+    result = getTypeDescAux(m, t, check)
+
+proc paramStorageLoc(param: PSym): TStorageLoc =
+  if param.typ.skipTypes({tyVar, tyTypeDesc}).kind notin {tyArray, tyOpenArray}:
+    result = OnStack
+  else:
+    result = OnUnknown
+
+proc genProcParams(m: BModule, t: PType, rettype, params: var PRope, 
+                   check: var IntSet, declareEnvironment=true) = 
+  params = nil
+  if (t.sons[0] == nil) or isInvalidReturnType(t.sons[0]): 
+    rettype = ~"void"
+  else: 
+    rettype = getTypeDescAux(m, t.sons[0], check)
+  for i in countup(1, sonsLen(t.n) - 1): 
+    if t.n.sons[i].kind != nkSym: internalError(t.n.info, "genProcParams")
+    var param = t.n.sons[i].sym
+    if isCompileTimeOnly(param.typ): continue
+    if params != nil: app(params, ~", ")
+    fillLoc(param.loc, locParam, param.typ, mangleName(param),
+            param.paramStorageLoc)
+    if ccgIntroducedPtr(param): 
+      app(params, getTypeDescWeak(m, param.typ, check))
+      app(params, ~"*")
+      incl(param.loc.flags, lfIndirect)
+      param.loc.s = OnUnknown
+    else:
+      app(params, getTypeDescAux(m, param.typ, check))
+    app(params, ~" ")
+    app(params, param.loc.r)
+    # declare the len field for open arrays:
+    var arr = param.typ
+    if arr.kind == tyVar: arr = arr.sons[0]
+    var j = 0
+    while arr.kind in {tyOpenArray, tyVarargs}:
+      # this fixes the 'sort' bug:
+      if param.typ.kind == tyVar: param.loc.s = OnUnknown
+      # need to pass hidden parameter:
+      appf(params, ", NI $1Len$2", [param.loc.r, j.toRope])
+      inc(j)
+      arr = arr.sons[0]
+  if (t.sons[0] != nil) and isInvalidReturnType(t.sons[0]):
+    var arr = t.sons[0]
+    if params != nil: app(params, ", ")
+    if (mapReturnType(t.sons[0]) != ctArray):
+      app(params, getTypeDescWeak(m, arr, check))
+      app(params, "*")
+    else:
+      app(params, getTypeDescAux(m, arr, check))
+    appf(params, " Result", [])
+  if t.callConv == ccClosure and declareEnvironment: 
+    if params != nil: app(params, ", ")
+    app(params, "void* ClEnv")
+  if tfVarargs in t.flags:
+    if params != nil: app(params, ", ")
+    app(params, "...")
+  if params == nil: app(params, "void)")
+  else: app(params, ")")
+  params = con("(", params)
   
 proc mangleRecFieldName(field: PSym, rectype: PType): PRope = 
   if (rectype.sym != nil) and
@@ -473,9 +488,6 @@ proc getTupleDesc(m: BModule, typ: PType, name: PRope,
   else: app(result, desc)
   app(result, "};" & tnl)
 
-proc pushType(m: BModule, typ: PType) = 
-  add(m.typeStack, typ)
-
 proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope = 
   # returns only the type's name
   var t = getUniqueType(typ)
^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65