lots of C++ codegen improvements

This commit is contained in:
Araq 2015-02-06 21:26:40 +01:00
commit e84834db79
10 changed files with 71 additions and 119 deletions

View file

@ -124,8 +124,8 @@ proc genArgStringToCString(p: BProc, n: PNode): PRope {.inline.} =
var a: TLoc
initLocExpr(p, n.sons[0], a)
result = ropef("$1->data", [a.rdLoc])
proc genArg(p: BProc, n: PNode, param: PSym): PRope =
proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): PRope =
var a: TLoc
if n.kind == nkStringToCString:
result = genArgStringToCString(p, n)
@ -138,7 +138,15 @@ proc genArg(p: BProc, n: PNode, param: PSym): PRope =
elif p.module.compileToCpp and param.typ.kind == tyVar and
n.kind == nkHiddenAddr:
initLocExprSingleUse(p, n.sons[0], a)
result = rdLoc(a)
# if the proc is 'importc'ed but not 'importcpp'ed then 'var T' still
# means '*T'. See posix.nim for lots of examples that do that in the wild.
let callee = call.sons[0]
if callee.kind == nkSym and
{sfImportC, sfInfixCall, sfCompilerProc} * callee.sym.flags == {sfImportC} and
{lfHeader, lfNoDecl} * callee.sym.loc.flags != {}:
result = addrLoc(a)
else:
result = rdLoc(a)
else:
initLocExprSingleUse(p, n, a)
result = rdLoc(a)
@ -166,7 +174,7 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
if params != nil: app(params, ~", ")
if i < sonsLen(typ):
assert(typ.n.sons[i].kind == nkSym)
app(params, genArg(p, ri.sons[i], typ.n.sons[i].sym))
app(params, genArg(p, ri.sons[i], typ.n.sons[i].sym, ri))
else:
app(params, genArgNoParam(p, ri.sons[i]))
fixupCall(p, le, ri, d, op.r, params)
@ -192,7 +200,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
assert(sonsLen(typ) == sonsLen(typ.n))
if i < sonsLen(typ):
assert(typ.n.sons[i].kind == nkSym)
app(pl, genArg(p, ri.sons[i], typ.n.sons[i].sym))
app(pl, genArg(p, ri.sons[i], typ.n.sons[i].sym, ri))
else:
app(pl, genArgNoParam(p, ri.sons[i]))
if i < length - 1: app(pl, ~", ")
@ -424,12 +432,12 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
assert(sonsLen(typ) == sonsLen(typ.n))
if length > 1:
app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym))
app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri))
app(pl, ~" ")
app(pl, op.r)
if length > 2:
app(pl, ~": ")
app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym))
app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri))
for i in countup(3, length-1):
assert(sonsLen(typ) == sonsLen(typ.n))
if i >= sonsLen(typ):
@ -439,7 +447,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
app(pl, ~" ")
app(pl, param.name.s)
app(pl, ~": ")
app(pl, genArg(p, ri.sons[i], param))
app(pl, genArg(p, ri.sons[i], param, ri))
if typ.sons[0] != nil:
if isInvalidReturnType(typ.sons[0]):
if sonsLen(ri) > 1: app(pl, ~" ")