From 910ef7b2d109f7516f8dab054bd0d41ff733047a Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 18 Mar 2015 00:46:10 +0100 Subject: 'constructor' pragma for C++ support --- compiler/ast.nim | 10 ++--- compiler/ccgstmts.nim | 18 ++++++-- compiler/cgen.nim | 12 +----- compiler/pragmas.nim | 7 +++- compiler/transf.nim | 3 +- compiler/wordrecg.nim | 114 +++++++++++++++++++++++++------------------------- doc/nimc.txt | 16 ++++++- 7 files changed, 98 insertions(+), 82 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 274a49b52..660f3e45e 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -257,7 +257,7 @@ type sfThread, # proc will run as a thread # variable is a thread variable sfCompileTime, # proc can be evaluated at compile time - sfMerge, # proc can be merged with itself + sfConstructor, # proc is a C++ constructor sfDeadCodeElim, # dead code elimination for the module is turned on sfBorrow, # proc is borrowed sfInfixCall, # symbol needs infix call syntax in target language; @@ -663,7 +663,9 @@ type locOther # location is something other TLocFlag* = enum lfIndirect, # backend introduced a pointer - lfParamCopy, # backend introduced a parameter copy (LLVM) + lfFullExternalName, # only used when 'gCmd == cmdPretty': Indicates + # that the symbol has been imported via 'importc: "fullname"' and + # no format string. lfNoDeepCopy, # no need for a deep copy lfNoDecl, # do not declare it in C lfDynamicLib, # link symbol to dynamic library @@ -915,10 +917,6 @@ const skIterators* = {skIterator, skClosureIterator} - lfFullExternalName* = lfParamCopy # \ - # only used when 'gCmd == cmdPretty': Indicates that the symbol has been - # imported via 'importc: "fullname"' and no format string. - var ggDebug* {.deprecated.}: bool ## convenience switch for trying out things proc isCallExpr*(n: PNode): bool = diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 12bf069bf..441ceb22a 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -202,7 +202,8 @@ proc genSingleVar(p: BProc, a: PNode) = genVarPrototypeAux(generatedHeader, v) registerGcRoot(p, v) else: - let imm = isAssignedImmediately(a.sons[2]) + let value = a.sons[2] + let imm = isAssignedImmediately(value) 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 @@ -211,8 +212,19 @@ proc genSingleVar(p: BProc, a: PNode) = genLineDir(p, a) let decl = localVarDecl(p, v) var tmp: TLoc - initLocExprSingleUse(p, a.sons[2], tmp) - lineF(p, cpsStmts, "$# = $#;$n", decl, tmp.rdLoc) + if value.kind in nkCallKinds and value[0].kind == nkSym and + sfConstructor in value[0].sym.flags: + var params: PRope + let typ = skipTypes(value.sons[0].typ, abstractInst) + assert(typ.kind == tyProc) + for i in 1..