summary refs log tree commit diff stats
path: root/tests/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/cpp')
-rw-r--r--tests/cpp/23962.h17
-rw-r--r--tests/cpp/fam.h4
-rw-r--r--tests/cpp/t22679.nim50
-rw-r--r--tests/cpp/t22680.nim50
-rw-r--r--tests/cpp/t22712.nim15
-rw-r--r--tests/cpp/t23306.nim12
-rw-r--r--tests/cpp/t23434.nim17
-rw-r--r--tests/cpp/t23657.nim54
-rw-r--r--tests/cpp/t23962.nim32
-rw-r--r--tests/cpp/tcasts.nim3
-rw-r--r--tests/cpp/tconstructor.nim84
-rw-r--r--tests/cpp/tfam.nim7
-rw-r--r--tests/cpp/tinitializers.nim60
-rw-r--r--tests/cpp/tmember.nim13
-rw-r--r--tests/cpp/tmember_forward_declaration.nim27
-rw-r--r--tests/cpp/tnoinitfield.nim30
-rw-r--r--tests/cpp/torc.nim34
-rw-r--r--tests/cpp/tvirtual.nim10
-rw-r--r--tests/cpp/virtualptr.nim9
19 files changed, 520 insertions, 8 deletions
diff --git a/tests/cpp/23962.h b/tests/cpp/23962.h
new file mode 100644
index 000000000..2d8147bfb
--- /dev/null
+++ b/tests/cpp/23962.h
@@ -0,0 +1,17 @@
+#include <iostream>
+
+struct Foo {
+
+  Foo(int inX): x(inX) {
+    std::cout << "Ctor Foo(" << x << ")\n";
+  }
+  ~Foo() {
+    std::cout << "Destory Foo(" << x << ")\n";
+  }
+
+  void print() {
+    std::cout << "Foo.x = " << x << '\n';
+  }
+
+  int x;
+};
\ No newline at end of file
diff --git a/tests/cpp/fam.h b/tests/cpp/fam.h
new file mode 100644
index 000000000..ad576425b
--- /dev/null
+++ b/tests/cpp/fam.h
@@ -0,0 +1,4 @@
+struct Test{
+  ~Test() {
+  }
+};
diff --git a/tests/cpp/t22679.nim b/tests/cpp/t22679.nim
new file mode 100644
index 000000000..81defcb58
--- /dev/null
+++ b/tests/cpp/t22679.nim
@@ -0,0 +1,50 @@
+discard """
+  cmd: "nim cpp $file"
+  output:'''
+cppNZ.x = 123
+cppNZInit.x = 123
+hascpp.cppnz.x = 123
+hasCppInit.cppnz.x = 123
+hasCppCtor.cppnz.x = 123
+'''
+"""
+{.emit:"""/*TYPESECTION*/
+struct CppNonZero {
+  int x = 123;
+};
+""".}
+
+import sugar
+type
+  CppNonZero {.importcpp, inheritable.} = object
+    x: cint
+
+  HasCpp = object
+    cppnz: CppNonZero
+
+proc initCppNonZero: CppNonZero =
+  CppNonZero()
+
+proc initHasCpp: HasCpp =
+  HasCpp()
+
+proc ctorHasCpp: HasCpp {.constructor.} =
+  discard
+
+proc main =
+  var cppNZ: CppNonZero
+  dump cppNZ.x
+
+  var cppNZInit = initCppNonZero()
+  dump cppNZInit.x
+
+  var hascpp: HasCpp
+  dump hascpp.cppnz.x
+
+  var hasCppInit = initHasCpp()
+  dump hasCppInit.cppnz.x
+
+  var hasCppCtor = ctorHasCpp()
+  dump hasCppCtor.cppnz.x
+
+main()
\ No newline at end of file
diff --git a/tests/cpp/t22680.nim b/tests/cpp/t22680.nim
new file mode 100644
index 000000000..80f1a8319
--- /dev/null
+++ b/tests/cpp/t22680.nim
@@ -0,0 +1,50 @@
+discard """
+  cmd: "nim cpp $file"
+  output:'''
+cppNZ.x = 123
+cppNZInit.x = 123
+inheritCpp.x = 123
+inheritCppInit.x = 123
+inheritCppCtor.x = 123
+'''
+"""
+import std/sugar
+
+{.emit:"""/*TYPESECTION*/
+struct CppNonZero {
+  int x = 123;
+};
+""".}
+
+type
+  CppNonZero {.importcpp, inheritable.} = object
+    x: cint
+
+  InheritCpp = object of CppNonZero
+
+proc initCppNonZero: CppNonZero =
+  CppNonZero()
+
+proc initInheritCpp: InheritCpp =
+  InheritCpp()
+
+proc ctorInheritCpp: InheritCpp {.constructor.} =
+  discard
+
+proc main =
+  var cppNZ: CppNonZero
+  dump cppNZ.x
+
+  var cppNZInit = initCppNonZero()
+  dump cppNZInit.x
+
+  var inheritCpp: InheritCpp
+  dump inheritCpp.x
+
+  var inheritCppInit = initInheritCpp()
+  dump inheritCppInit.x
+
+  var inheritCppCtor = ctorInheritCpp()
+  dump inheritCppCtor.x
+
+main()
\ No newline at end of file
diff --git a/tests/cpp/t22712.nim b/tests/cpp/t22712.nim
new file mode 100644
index 000000000..34ef67ac8
--- /dev/null
+++ b/tests/cpp/t22712.nim
@@ -0,0 +1,15 @@
+discard """
+targets: "cpp"
+errormsg: "constructor in an imported type needs importcpp pragma"
+line: 14
+"""
+{.emit: """/*TYPESECTION*/
+struct CppStruct {
+  CppStruct();
+};
+""".}
+
+type CppStruct {.importcpp.} = object
+
+proc makeCppStruct(): CppStruct {.constructor.} = 
+  discard
\ No newline at end of file
diff --git a/tests/cpp/t23306.nim b/tests/cpp/t23306.nim
new file mode 100644
index 000000000..ebb4edb8d
--- /dev/null
+++ b/tests/cpp/t23306.nim
@@ -0,0 +1,12 @@
+discard """
+targets: "cpp"
+"""
+
+type K = object
+  h: iterator(f: K): K
+
+iterator d(g: K): K {.closure.} =
+  defer:
+    discard
+
+discard K(h: d)
\ No newline at end of file
diff --git a/tests/cpp/t23434.nim b/tests/cpp/t23434.nim
new file mode 100644
index 000000000..04a83227e
--- /dev/null
+++ b/tests/cpp/t23434.nim
@@ -0,0 +1,17 @@
+discard """
+cmd:"nim cpp $file"
+errormsg: "type mismatch: got <proc (self: SomeObject){.member, gcsafe.}>"
+line: 17
+"""
+type SomeObject = object
+    value: int
+
+proc printValue(self: SomeObject) {.virtual.} =
+    echo "The value is ", self.value
+
+proc callAProc(p: proc(self: SomeObject){.noconv.}) =
+    let someObj = SomeObject(value: 4)
+    echo "calling param proc"
+    p(someObj)
+
+callAProc(printValue)
\ No newline at end of file
diff --git a/tests/cpp/t23657.nim b/tests/cpp/t23657.nim
new file mode 100644
index 000000000..63deb7fb0
--- /dev/null
+++ b/tests/cpp/t23657.nim
@@ -0,0 +1,54 @@
+discard """
+  targets: "cpp"
+  cmd: "nim cpp -r $file"
+  output: '''
+1.0
+1.0
+'''
+
+"""
+{.emit:"""/*TYPESECTION*/
+struct Point {
+  float x, y, z;
+  Point(float x, float y, float z): x(x), y(y), z(z) {}
+  Point() = default;
+};
+struct Direction {
+  float x, y, z;
+  Direction(float x, float y, float z): x(x), y(y), z(z) {}
+  Direction() = default;
+};
+struct Axis {
+  Point origin;
+  Direction direction;
+  Axis(Point origin, Direction direction): origin(origin), direction(direction) {}
+  Axis() = default;
+};
+
+""".}
+
+type
+  Point {.importcpp.} = object
+    x, y, z: float
+  
+  Direction {.importcpp.} = object
+    x, y, z: float
+
+  Axis {.importcpp.} = object
+    origin: Point
+    direction: Direction
+
+proc makeAxis(origin: Point, direction: Direction): Axis {. constructor, importcpp:"Axis(@)".}
+proc makePoint(x, y, z: float): Point {. constructor, importcpp:"Point(@)".}
+proc makeDirection(x, y, z: float): Direction {. constructor, importcpp:"Direction(@)".}
+
+var axis1 = makeAxis(Point(x: 1.0, y: 2.0, z: 3.0), Direction(x: 4.0, y: 5.0, z: 6.0)) #Triggers the error (T1)
+var axis2Ctor = makeAxis(makePoint(1.0, 2.0, 3.0), makeDirection(4.0, 5.0, 6.0)) #Do not triggers
+
+proc main() = #Do not triggers as Tx are inside the body
+  let test = makeAxis(Point(x: 1.0, y: 2.0, z: 3.0), Direction(x: 4.0, y: 5.0, z: 6.0))
+  echo test.origin.x
+
+main()
+
+echo $axis1.origin.x  #Make sures it's init
\ No newline at end of file
diff --git a/tests/cpp/t23962.nim b/tests/cpp/t23962.nim
new file mode 100644
index 000000000..c79d888df
--- /dev/null
+++ b/tests/cpp/t23962.nim
@@ -0,0 +1,32 @@
+discard """
+  cmd: "nim cpp $file"
+  output: '''
+Ctor Foo(-1)
+Destory Foo(-1)
+Ctor Foo(-1)
+Destory Foo(-1)
+Ctor Foo(-1)
+Destory Foo(-1)
+Foo.x = 1
+Foo.x = 2
+Foo.x = -1
+'''
+"""
+
+type
+  Foo {.importcpp, header: "23962.h".} = object
+    x: cint
+
+proc print(f: Foo) {.importcpp.}
+
+#also tests the right constructor is used
+proc makeFoo(x: int32 = -1): Foo {.importcpp:"Foo(#)", constructor.} 
+
+proc test =
+  var xs = newSeq[Foo](3)
+  xs[0].x = 1
+  xs[1].x = 2
+  for x in xs:
+    x.print
+
+test()
\ No newline at end of file
diff --git a/tests/cpp/tcasts.nim b/tests/cpp/tcasts.nim
index d968d87db..80527efff 100644
--- a/tests/cpp/tcasts.nim
+++ b/tests/cpp/tcasts.nim
@@ -1,6 +1,5 @@
 discard """
   cmd: "nim cpp $file"
-  output: '''{"vas": "kas", "123": "123"}'''
   targets: "cpp"
 """
 
@@ -18,4 +17,4 @@ import tables
 var t = initTable[string, string]()
 discard t.hasKeyOrPut("123", "123")
 discard t.mgetOrPut("vas", "kas")
-echo t
\ No newline at end of file
+doAssert t.len == 2
diff --git a/tests/cpp/tconstructor.nim b/tests/cpp/tconstructor.nim
index d4d6a7ccf..922ee54fd 100644
--- a/tests/cpp/tconstructor.nim
+++ b/tests/cpp/tconstructor.nim
@@ -3,6 +3,20 @@ discard """
   cmd: "nim cpp $file"
   output: '''
 1
+0
+123
+0
+123
+___
+0
+777
+10
+123
+0
+777
+10
+123
+()
 '''
 """
 
@@ -33,7 +47,7 @@ type NimClassNoNarent* = object
   x: int32
 
 proc makeNimClassNoParent(x:int32): NimClassNoNarent {. constructor.} =
-  this.x = x
+  result.x = x
   discard
 
 let nimClassNoParent = makeNimClassNoParent(1)
@@ -45,11 +59,73 @@ var nimClassNoParentDef {.used.}: NimClassNoNarent  #test has a default construc
 type NimClass* = object of CppClass
 
 proc makeNimClass(x:int32): NimClass {. constructor:"NimClass('1 #1) : CppClass(0, #1) ".} =
-  this.x = x
+  result.x = x
 
 #optinially define the default constructor so we get rid of the cpp warn and we can declare the obj (note: default constructor of 'tyObject_NimClass__apRyyO8cfRsZtsldq1rjKA' is implicitly deleted because base class 'CppClass' has no default constructor)
 proc makeCppClass(): NimClass {. constructor: "NimClass() : CppClass(0, 0) ".} = 
-  this.x = 1
+  result.x = 1
 
 let nimClass = makeNimClass(1)
-var nimClassDef {.used.}: NimClass  #since we explictly defined the default constructor we can declare the obj
\ No newline at end of file
+var nimClassDef {.used.}: NimClass  #since we explictly defined the default constructor we can declare the obj
+
+#bug: 22662
+type
+  BugClass* = object
+    x: int          # Not initialized
+
+proc makeBugClass(): BugClass {.constructor.} =
+  discard
+
+proc main =
+  for i in 0 .. 1:
+    var n = makeBugClass()
+    echo n.x
+    n.x = 123
+    echo n.x
+
+main()
+#bug:
+echo "___"
+type
+  NimClassWithDefault = object
+    x: int
+    y = 777
+    case kind: bool = true
+    of true:
+      z: int = 10
+    else: discard
+
+proc makeNimClassWithDefault(): NimClassWithDefault {.constructor.} =
+  result = NimClassWithDefault()
+
+proc init =
+  for i in 0 .. 1:
+    var n = makeNimClassWithDefault()
+    echo n.x
+    echo n.y
+    echo n.z
+    n.x = 123
+    echo n.x
+
+init()
+
+#tests that the ctor is not declared with nodecl. 
+#nodelc also prevents the creation of a default one when another is created.
+type Foo {.exportc.} = object
+
+proc makeFoo(): Foo {.used, constructor, nodecl.} = discard
+
+echo $Foo()
+
+type Boo = object
+proc `=copy`(dest: var Boo; src: Boo) = discard
+
+proc makeBoo(): Boo {.constructor.} = Boo()
+proc makeBoo2(): Boo  = Boo()
+
+block:
+  proc main =
+    var b = makeBoo()
+    var b2 = makeBoo2()
+
+  main()
\ No newline at end of file
diff --git a/tests/cpp/tfam.nim b/tests/cpp/tfam.nim
new file mode 100644
index 000000000..6bd89fe24
--- /dev/null
+++ b/tests/cpp/tfam.nim
@@ -0,0 +1,7 @@
+discard """
+  targets: "cpp"
+"""
+type 
+  Test {.importcpp, header: "fam.h".} = object
+
+let test = newSeq[Test]()
\ No newline at end of file
diff --git a/tests/cpp/tinitializers.nim b/tests/cpp/tinitializers.nim
new file mode 100644
index 000000000..0199fb96b
--- /dev/null
+++ b/tests/cpp/tinitializers.nim
@@ -0,0 +1,60 @@
+discard """
+  cmd: "nim cpp $file"
+"""
+
+{.emit:"""/*TYPESECTION*/
+struct CppStruct {
+  CppStruct(int x, char* y): x(x), y(y){}
+  void doSomething() {}
+  int x;
+  char* y;
+};
+""".}
+type
+  CppStruct {.importcpp, inheritable.} = object
+  ChildStruct = object of CppStruct
+  HasCppStruct = object
+    cppstruct: CppStruct 
+
+proc constructCppStruct(a:cint = 5, b:cstring = "hello"): CppStruct {.importcpp: "CppStruct(@)", constructor.}
+proc doSomething(this: CppStruct) {.importcpp.}
+proc returnCppStruct(): CppStruct = discard
+proc initChildStruct: ChildStruct = ChildStruct() 
+proc makeChildStruct(): ChildStruct {.constructor:"""ChildStruct(): CppStruct(5, "10")""".} = discard
+proc initHasCppStruct(x: cint): HasCppStruct =
+  HasCppStruct(cppstruct: constructCppStruct(x))
+
+proc main =
+  var hasCppStruct = initHasCppStruct(2) #generates cppstruct = { 10 } inside the struct
+  hasCppStruct.cppstruct.doSomething() 
+  discard returnCppStruct() #generates result = { 10 } 
+  discard initChildStruct() #generates ChildStruct temp ({}) bypassed with makeChildStruct
+  (proc (s:CppStruct) = discard)(CppStruct()) #CppStruct temp ({10})
+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
diff --git a/tests/cpp/tmember.nim b/tests/cpp/tmember.nim
index 07bd5e0ee..1a5b6fd97 100644
--- a/tests/cpp/tmember.nim
+++ b/tests/cpp/tmember.nim
@@ -8,6 +8,8 @@ hello foo
 hello boo
 hello boo
 FunctorSupport!
+static
+static
 destructing
 destructing
 '''
@@ -34,7 +36,7 @@ echo doo == Doo(test: 1)
 #virtual
 proc newCpp*[T](): ptr T {.importcpp:"new '*0()".}
 type 
-  Foo = object of RootObj
+  Foo {.exportc.} = object of RootObj
   FooPtr = ptr Foo
   Boo = object of Foo
   BooPtr = ptr Boo
@@ -62,3 +64,12 @@ proc invoke(f: NimFunctor, n:int) {.member:"operator ()('2 #2)" .} =
 {.experimental: "callOperator".}
 proc `()`(f: NimFunctor, n:int) {.importcpp:"#(@)" .} 
 NimFunctor()(1)
+
+#static
+proc staticProc(self: FooPtr) {.member: "static $1()".} = 
+  echo "static"
+
+proc importedStaticProc() {.importcpp:"Foo::staticProc()".}
+
+foo.staticProc()
+importedStaticProc()
diff --git a/tests/cpp/tmember_forward_declaration.nim b/tests/cpp/tmember_forward_declaration.nim
new file mode 100644
index 000000000..2f4a79daa
--- /dev/null
+++ b/tests/cpp/tmember_forward_declaration.nim
@@ -0,0 +1,27 @@
+discard """
+  targets: "cpp"
+  cmd: "nim cpp $file"
+  output: '''
+abc called
+def called
+abc called
+'''
+"""
+
+type Foo = object
+
+proc abc(this: Foo, x: int): void {.member: "$1('2 #2)".}
+proc def(this: Foo, y: int): void {.virtual: "$1('2 #2)".}
+
+proc abc(this: Foo, x: int): void =
+  echo "abc called"
+  if x > 0:
+    this.def(x - 1)
+
+proc def(this: Foo, y: int): void =
+  echo "def called"
+  this.abc(y)
+
+var x = Foo()
+x.abc(1)
+
diff --git a/tests/cpp/tnoinitfield.nim b/tests/cpp/tnoinitfield.nim
new file mode 100644
index 000000000..4deffece8
--- /dev/null
+++ b/tests/cpp/tnoinitfield.nim
@@ -0,0 +1,30 @@
+discard """
+  targets: "cpp"
+  cmd: "nim cpp $file"
+  output: '''
+'''
+"""
+{.emit: """/*TYPESECTION*/
+  struct Foo {
+    Foo(int a){};
+  };
+  struct Boo {
+    Boo(int a){};
+  };
+
+  """.}
+
+type 
+  Foo {.importcpp.} = object
+  Boo {.importcpp, noInit.} = object
+  Test {.exportc.} = object
+    foo {.noInit.}: Foo
+    boo: Boo
+
+proc makeTest(): Test {.constructor: "Test() : foo(10), boo(1)".} = 
+  discard
+
+proc main() = 
+  var t = makeTest()
+
+main()
\ No newline at end of file
diff --git a/tests/cpp/torc.nim b/tests/cpp/torc.nim
index 64c6c0e5f..9f1a41a21 100644
--- a/tests/cpp/torc.nim
+++ b/tests/cpp/torc.nim
@@ -39,3 +39,37 @@ proc asVector*[T](t: T): EnumVector[T] =
 # N_NIMCALL(std::vector<> , asvector_106028_3197418230)(SomeEnum t0)
 
 discard asVector(SomeEnum.A)
+
+
+block: # bug #10219
+  type
+    Vector[T]  {.importcpp: "std::vector", header: "vector".} = object
+
+  proc initVector[T](n: csize_t): Vector[T] 
+      {.importcpp: "std::vector<'*0>(@)", header: "vector".}
+
+  proc unsafeIndex[T](this: var Vector[T], i: csize_t): var T 
+      {.importcpp: "#[#]", header: "vector".}
+
+  proc `[]`[T](this: var Vector[T], i: Natural): var T {.inline, noinit.} =
+    when compileOption("boundChecks"):
+        # this.checkIndex i
+        discard
+    result = this.unsafeIndex(csize_t(i))
+
+  var v1 = initVector[int](10)
+  doAssert v1[0] == 0
+
+block: # bug #12703 bug #19588
+  type
+    cstringConstImpl {.importc:"const char*".} = cstring
+    constChar = distinct cstringConstImpl
+
+  {.emit: """
+  const char* foo() {
+    return "hello";
+  }
+  """.}
+  proc foo(): constChar {.importcpp.} # change to importcpp for C++ backend
+  doAssert $(foo().cstring) == "hello"
+
diff --git a/tests/cpp/tvirtual.nim b/tests/cpp/tvirtual.nim
index fb792380b..385d052b8 100644
--- a/tests/cpp/tvirtual.nim
+++ b/tests/cpp/tvirtual.nim
@@ -115,4 +115,12 @@ proc test(self: Child): Box[Inner] {.virtual, asmnostackframe.} =
   {.emit:"return res;".}
   
 
-discard Child().test() 
\ No newline at end of file
+discard Child().test() 
+
+import virtualptr
+
+#We dont want to pull Loo directly by using it as we are testing that the pointer pulls it. 
+proc makeMoo(): Moo {.importcpp:"{ new Loo() }".}
+
+makeMoo().loo.salute()
+
diff --git a/tests/cpp/virtualptr.nim b/tests/cpp/virtualptr.nim
new file mode 100644
index 000000000..f96264081
--- /dev/null
+++ b/tests/cpp/virtualptr.nim
@@ -0,0 +1,9 @@
+type 
+  Loo* {.exportc.} = object
+  LooPtr* = ptr Loo
+  Moo* {.exportc.} = object 
+    loo*: LooPtr
+
+
+proc salute*(foo: LooPtr) {.virtual.} = 
+  discard