diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index fb878a83e9..200ff91e03 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -133,7 +133,7 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): PRope = var n = if n.kind != nkHiddenAddr: n else: n.sons[0] result = openArrayLoc(p, n) elif ccgIntroducedPtr(param): - initLocExprSingleUse(p, n, a) + initLocExpr(p, n, a) result = addrLoc(a) elif p.module.compileToCpp and param.typ.kind == tyVar and n.kind == nkHiddenAddr: diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 61568c9e62..a4938c9ac1 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -203,7 +203,8 @@ proc genSingleVar(p: BProc, a: PNode) = registerGcRoot(p, v) else: let imm = isAssignedImmediately(a.sons[2]) - if imm and p.module.compileToCpp and p.splitDecls == 0: + if imm and p.module.compileToCpp and p.splitDecls == 0 and + not containsHiddenPointer(v.typ): # C++ really doesn't like things like 'Foo f; f = x' as that invokes a # parameterless constructor followed by an assignment operator. So we # generate better code here: diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index e4ce0aa6c9..134619d4a2 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -69,7 +69,20 @@ when false: proc echoStats*() = for i in countup(low(TTypeKind), high(TTypeKind)): echo i, " ", gTypeTable[i].counter - + +proc slowSearch(key: PType; k: TTypeKind): PType = + # tuples are quite horrible as C does not support them directly and + # tuple[string, string] is a (strange) subtype of + # tuple[nameA, nameB: string]. This bites us here, so we + # use 'sameBackendType' instead of 'sameType'. + if idTableHasObjectAsKey(gTypeTable[k], key): return key + for h in countup(0, high(gTypeTable[k].data)): + var t = PType(gTypeTable[k].data[h].key) + if t != nil and sameBackendType(t, key): + return t + idTablePut(gTypeTable[k], key, key) + result = key + proc getUniqueType*(key: PType): PType = # this is a hotspot in the compiler! if key == nil: return @@ -96,23 +109,20 @@ proc getUniqueType*(key: PType): PType = #if obj.sym != nil and obj.sym.name.s == "TOption": # echo "for ", typeToString(key), " I returned " # debug result + of tyPtr, tyRef, tyVar: + let elemType = lastSon(key) + if elemType.kind in {tyBool, tyChar, tyInt..tyUInt64}: + # no canonicalization for integral types, so that e.g. ``ptr pid_t`` is + # produced instead of ``ptr NI``. + result = key + else: + result = slowSearch(key, k) of tyArrayConstr, tyGenericInvocation, tyGenericBody, tyOpenArray, tyArray, tySet, tyRange, tyTuple, - tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy, tyVar: - # tuples are quite horrible as C does not support them directly and - # tuple[string, string] is a (strange) subtype of - # tuple[nameA, nameB: string]. This bites us here, so we - # use 'sameBackendType' instead of 'sameType'. - + tySequence, tyForward, tyVarargs, tyProxy: # we have to do a slow linear search because types may need # to be compared by their structure: - if idTableHasObjectAsKey(gTypeTable[k], key): return key - for h in countup(0, high(gTypeTable[k].data)): - var t = PType(gTypeTable[k].data[h].key) - if t != nil and sameBackendType(t, key): - return t - idTablePut(gTypeTable[k], key, key) - result = key + result = slowSearch(key, k) of tyObject: if tfFromGeneric notin key.flags: # fast case; lookup per id suffices: @@ -139,14 +149,8 @@ proc getUniqueType*(key: PType): PType = result = key else: # ugh, we need the canon here: - if idTableHasObjectAsKey(gTypeTable[k], key): return key - for h in countup(0, high(gTypeTable[k].data)): - var t = PType(gTypeTable[k].data[h].key) - if t != nil and sameBackendType(t, key): - return t - idTablePut(gTypeTable[k], key, key) - result = key - + result = slowSearch(key, k) + proc tableGetType*(tab: TIdTable, key: PType): RootRef = # returns nil if we need to declare this type result = idTableGet(tab, key) diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index 5d68d112e6..a05398a095 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -188,7 +188,7 @@ when defined(windows) and not defined(useWinAnsi): proc wfopen(filename, mode: WideCString): pointer {. importcpp: "_wfopen((const wchar_t*)#, (const wchar_t*)#)", nodecl.} proc wfreopen(filename, mode: WideCString, stream: File): File {. - importc: "_wfreopen((const wchar_t*)#, (const wchar_t*)#)", nodecl.} + importcpp: "_wfreopen((const wchar_t*)#, (const wchar_t*)#, #)", nodecl.} else: proc wfopen(filename, mode: WideCString): pointer {. importc: "_wfopen", nodecl.} diff --git a/todo.txt b/todo.txt index 79fe9d05a3..3fed10aebb 100644 --- a/todo.txt +++ b/todo.txt @@ -10,6 +10,7 @@ version 0.10.4 version 1.0 =========== +- figure out why C++ bootstrapping is so much slower - nimsuggest: auto-completion needs to work in 'class' macros - improve the docs for inheritance - The bitwise 'not' operator will be renamed to 'bnot' to