summary refs log tree commit diff stats
path: root/tests/cpp/tconstructor.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/cpp/tconstructor.nim')
-rw-r--r--tests/cpp/tconstructor.nim131
1 files changed, 131 insertions, 0 deletions
diff --git a/tests/cpp/tconstructor.nim b/tests/cpp/tconstructor.nim
new file mode 100644
index 000000000..922ee54fd
--- /dev/null
+++ b/tests/cpp/tconstructor.nim
@@ -0,0 +1,131 @@
+discard """
+  targets: "cpp"
+  cmd: "nim cpp $file"
+  output: '''
+1
+0
+123
+0
+123
+___
+0
+777
+10
+123
+0
+777
+10
+123
+()
+'''
+"""
+
+{.emit:"""/*TYPESECTION*/
+struct CppClass {
+  int x;
+  int y;
+  CppClass(int inX, int inY) {
+    this->x = inX;
+    this->y = inY;
+  }
+  //CppClass() = default;
+};
+""".}
+
+type  CppClass* {.importcpp, inheritable.} = object
+  x: int32
+  y: int32
+
+proc makeCppClass(x, y: int32): CppClass {.importcpp: "CppClass(@)", constructor.}
+#test globals are init with the constructor call
+var shouldCompile {.used.} = makeCppClass(1, 2)
+
+proc newCpp*[T](): ptr T {.importcpp:"new '*0()".}
+
+#creation
+type NimClassNoNarent* = object
+  x: int32
+
+proc makeNimClassNoParent(x:int32): NimClassNoNarent {. constructor.} =
+  result.x = x
+  discard
+
+let nimClassNoParent = makeNimClassNoParent(1)
+echo nimClassNoParent.x #acess to this just fine. Notice the field will appear last because we are dealing with constructor calls here
+
+var nimClassNoParentDef {.used.}: NimClassNoNarent  #test has a default constructor. 
+
+#inheritance 
+type NimClass* = object of CppClass
+
+proc makeNimClass(x:int32): NimClass {. constructor:"NimClass('1 #1) : CppClass(0, #1) ".} =
+  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) ".} = 
+  result.x = 1
+
+let nimClass = makeNimClass(1)
+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
ghlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
version 0.9.6
=============

- scopes are still broken for generic instantiation!
- implicit deref for parameter matching

Concurrency
-----------

- 'deepCopy' needs to be instantiated for
  generics *when the type is constructed*
- test 'deepCopy'
- overloading of '='; general lift mechanism

- the disjoint checker needs to deal with 'a = spawn f(); g = spawn f()'
- implement 'foo[1..4] = spawn(f[4..7])'
- document the new 'spawn' and 'parallel' statements

Low priority:
- support for exception propagation? (hard to implement)
- the copying of the 'ref Promise' into the thead local storage only
  happens to work due to the write barrier's implementation
- implement lock levels --> first without the more complex race avoidance


Misc
----

- fix the bug that keeps 'defer' template from working
- make '--implicitStatic:on' the default
- fix the tuple unpacking in lambda bug
- make tuple unpacking work in a non-var/let context
- special rule for ``[]=``
- built-in 'getImpl'
- type API for macros; make 'spawn' a macro
- markAndSweepGC should expose an API for fibers
- prevent 'alloc(TypeWithGCedMemory)'
- some table related tests are wrong (memory usage checks)


Bugs
====

- bug: 'type T = ref T' not recognized as illegal recursion
- bug: type conversions concerning proc types are weird
- compilation of niminst takes way too long. looks like a regression
- docgen: sometimes effects are listed twice
- 'result' is not properly cleaned for NRVO --> use uninit checking instead
- blocks can "export" an identifier but the CCG generates {} for them ...


version 0.9.x
=============

- pragmas need 'bindSym' support
- pragmas need re-work: 'push' is dangerous, 'hasPragma' does not work
  reliably with user-defined pragmas
- memory manager: add a measure of fragmentation
- implement 'bits' pragmas
- we need a magic thisModule symbol
- provide --nilChecks:on|off
- ensure (ref T)(a, b) works as a type conversion and type constructor
- optimize 'genericReset'; 'newException' leads to code bloat
- stack-less GC


version 0.9.X
=============

- macros as type pragmas
- lazy overloading resolution:
  * special case ``tyStmt``
- FFI:
  * test: times.format with the FFI
- document NimMain and check whether it works for threading
- 'quote' without 'do' doesn't work: parser/grammar issue; could be supported


version 0.9.X
=============

- implement the missing features wrt inheritance
- better support for macros that rewrite procs
- macros need access to types and symbols (partially implemented)
- enforce 'simpleExpr' more often --> doesn't work; tkProc is
  part of primary!
- the typeDesc/expr unification is weird and only necessary because of
  the ambiguous a[T] construct: It would be easy to support a[expr] for
  generics but require a[.typeDesc] if that's required; this would also
  allow [.ref T.](x) for a more general type conversion construct; for
  templates that would work too: T([.ref int])


Concurrency/Effect system
=========================

- shared memory heap: ``shared ref`` etc. The only hard part in the GC is to
  "stop the world". However, it may be worthwhile to generate explicit 
  (or implicit) syncGC() calls in loops. Automatic loop injection seems
  troublesome, but maybe we can come up with a simple heuristic. (All procs
  that `new` shared memory are syncGC() candidates... But then 'new' itself
  calls syncGC() so that's pointless.) Hm instead of an heuristic simply
  provide a ``syncgc`` pragma to trigger compiler injection --> more general:
  an ``injectLoop`` pragma
- 'writes: []' effect; track reads/writes for shared types
- use the effect system for static deadlock prevention and race detection
- ``~`` operator for effects
- introduce 'noaddr' pragma to prevent taking the address of a location; this
  is very handy to prevent aliasing of global data


version 0.9.XX
==============

- make 'clamp' a magic for the range stuff
- better type syntax for functions and tuples: tuple(int, int); (int,int)->int


Memory safety
=============

- object branch transitions from low(selector) are unsafe! ---> Needs a 
  deprecation path
- object branch transitions can't work with the current 'reset'; add a 'reset'
  with an additional parameter --> simple:
  provide a 'reset(x, TObj(k: nkValue))' instead? why bother? '=' does the
  same.
- returning 'var T' is unsafe and needs some static analysis


GC
==

- precise stack marking; embrace C++ code generation for that
- marker procs for Boehm GC
- hybrid GC
- acyclic vs prunable; introduce GC hints
- use big blocks in the allocator
- object pooling support for *hard* realtime systems
- provide tool/API to track leaks/object counts
- resizing of strings/sequences could take into account the memory that
  is allocated


CGEN
====
- codegen should use "NIM_CAST" macro and respect aliasing rules for GCC
- ``restrict`` pragma + backend support
- 'const' objects including case objects


Not essential for 1.0.0
=======================

- allow implicit forward declarations of procs via a pragma (so that the
  wrappers can deactivate it): better solution: introduce the notion of a 
  'proc section' that is similar to a type section.
- implement the "snoopResult" pragma; no, make a strutils with string append
  semantics instead ...
- implement "closure tuple consists of a single 'ref'" optimization
- new feature: ``distinct T with operations``
- arglist as a type (iterator chaining); variable length type lists for generics
- implement marker procs for message passing
- implement closures that support nesting of *procs* > 1
- object constructors: static check for fields if discriminator is known at 
  compile time
- prove array accesses


Optimizations
=============

- optimize 'if' with a constant condition --> necessary in frontend for better
  dead code elimination; also necessary to prevent  ``if c > 0: 1 div c``
- escape analysis for string/seq seems to be easy to do too;
  even further write barrier specialization
- inlining of first class functions
- proc specialization in the code gen for write barrier specialization
- VM/optimizer: implement on the fly CSE