diff options
-rw-r--r-- | compiler/ccgtypes.nim | 13 | ||||
-rw-r--r-- | tests/cpp/tpassbypragmas.nim | 27 |
2 files changed, 37 insertions, 3 deletions
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index e4a0fe84b..2aa92c130 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -18,6 +18,7 @@ type TypeDescKind = enum dkParam #skParam dkRefParam #param passed by ref when {.byref.} is used. Cpp only. C goes straight to dkParam and is handled as a regular pointer + dkRefGenericParam #param passed by ref when {.byref.} is used that is also a generic. Cpp only. C goes straight to dkParam and is handled as a regular pointer dkVar #skVar dkField #skField dkResult #skResult @@ -519,7 +520,10 @@ proc genMemberProcParams(m: BModule; prc: PSym, superCall, rettype, params: var var param = t.n[i].sym var descKind = dkParam if optByRef in param.options: - descKind = dkRefParam + if param.typ.kind == tyGenericInst: + descKind = dkRefGenericParam + else: + descKind = dkRefParam var typ, name : string fillParamName(m, param) fillLoc(param.loc, locParam, t.n[i], @@ -570,7 +574,10 @@ proc genProcParams(m: BModule; t: PType, rettype, params: var Rope, var param = t.n[i].sym var descKind = dkParam if m.config.backend == backendCpp and optByRef in param.options: - descKind = dkRefParam + if param.typ.kind == tyGenericInst: + descKind = dkRefGenericParam + else: + descKind = dkRefParam if isCompileTimeOnly(param.typ): continue if params != "(": params.add(", ") fillParamName(m, param) @@ -873,7 +880,7 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes result = getTypePre(m, t, sig) if result != "" and t.kind != tyOpenArray: excl(check, t.id) - if kind == dkRefParam: + if kind == dkRefParam or kind == dkRefGenericParam and origTyp.kind == tyGenericInst: result.add("&") return case t.kind diff --git a/tests/cpp/tpassbypragmas.nim b/tests/cpp/tpassbypragmas.nim new file mode 100644 index 000000000..f4301656a --- /dev/null +++ b/tests/cpp/tpassbypragmas.nim @@ -0,0 +1,27 @@ +discard """ + targets: "cpp" + cmd: "nim cpp $file" +""" +{.emit:"""/*TYPESECTION*/ + + template<typename T> + struct Box { + T first; + }; + struct Foo { + void test(void (*func)(Box<Foo>& another)){ + + }; + }; +""".} + +type + Foo {.importcpp.} = object + Box[T] {.importcpp:"Box<'0>".} = object + first: T + +proc test(self: Foo, fn: proc(another {.byref.}: Box[Foo]) {.cdecl.}) {.importcpp.} + +proc fn(another {.byref.} : Box[Foo]) {.cdecl.} = discard + +Foo().test(fn) \ No newline at end of file |