summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJuan M Gómez <info@jmgomez.me>2023-09-28 17:08:42 +0100
committerGitHub <noreply@github.com>2023-09-28 18:08:42 +0200
commit4fffa0960f6c17e9e1e6a20665c97ac34ea678bb (patch)
tree7efad6a6093e4fa27f14f6056bf258ac698322bb
parent285cbcb6aa36147e9b9c024ceed78e46526dd1ea (diff)
downloadNim-4fffa0960f6c17e9e1e6a20665c97ac34ea678bb.tar.gz
C++ Adds support for default arg using object construction syntax. Fixes a compiler crash (#22768)
`Foo()` below makes the compiler crash. 
```nim

proc makeBoo(a:cint = 10, b:cstring = "hello", foo: Foo = Foo()): Boo {.importcpp, constructor.}

```
-rw-r--r--compiler/ccgstmts.nim7
-rw-r--r--tests/cpp/tinitializers.nim31
2 files changed, 35 insertions, 3 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index c212ca0cb..c8f68c124 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -296,7 +296,12 @@ proc genCppParamsForCtor(p: BProc; call: PNode): string =
   assert(typ.kind == tyProc)
   for i in 1..<call.len:
     assert(typ.len == typ.n.len)
-    genOtherArg(p, call, i, typ, result, argsCounter)
+    #if it's a type we can just generate here another initializer as we are in an initializer context
+    if call[i].kind == nkCall and call[i][0].kind == nkSym and call[i][0].sym.kind == skType:
+      if argsCounter > 0: result.add ","
+      result.add genCppInitializer(p.module, p, call[i][0].sym.typ)
+    else:
+      genOtherArg(p, call, i, typ, result, argsCounter)
 
 proc genCppVarForCtor(p: BProc; call: PNode; decl: var Rope) =
   let params = genCppParamsForCtor(p, call)
diff --git a/tests/cpp/tinitializers.nim b/tests/cpp/tinitializers.nim
index 868cf825c..0199fb96b 100644
--- a/tests/cpp/tinitializers.nim
+++ b/tests/cpp/tinitializers.nim
@@ -1,5 +1,5 @@
 discard """
-  targets: "cpp"
+  cmd: "nim cpp $file"
 """
 
 {.emit:"""/*TYPESECTION*/
@@ -30,4 +30,31 @@ proc main =
   discard returnCppStruct() #generates result = { 10 } 
   discard initChildStruct() #generates ChildStruct temp ({}) bypassed with makeChildStruct
   (proc (s:CppStruct) = discard)(CppStruct()) #CppStruct temp ({10})
-main()
\ No newline at end of file
+main()
+
+
+#Should handle ObjectCalls
+{.emit:"""/*TYPESECTION*/
+struct Foo {
+};
+struct Boo {
+  Boo(int x, char* y, Foo f): x(x), y(y), foo(f){}
+  int x;
+  char* y;
+  Foo foo;
+};
+""".}
+type
+  Foo {.importcpp, inheritable, bycopy.} = object
+  Boo {.importcpp, inheritable.} = object
+    x: int32
+    y: cstring
+    foo: Foo
+
+proc makeBoo(a:cint = 10, b:cstring = "hello", foo: Foo = Foo()): Boo {.importcpp, constructor.}
+
+proc main2() = 
+  let cppStruct = makeBoo()
+  (proc (s:Boo) = discard)(Boo()) 
+
+main2()
\ No newline at end of file