Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Better handling of CPP static methods (#263)
* Better handling of CPP static methods

* Runtime flag & documentation

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
  • Loading branch information
Menduist and Araq committed Feb 22, 2023
1 parent e281d41 commit e65f463
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 2 deletions.
1 change: 1 addition & 0 deletions c2nim.nim
Expand Up @@ -74,6 +74,7 @@ Options:
--mergeDuplicates merge similar adjacent blocks like two let sections
--ignoreRValueRefs translate C++'s ``T&&`` to ``T`` instead ``of var T``
--keepBodies keep C++'s method bodies
--cppBindStatic bind cpp methods to their types
--concat concat the list of files into a single .nim file
--concat:all concat the list of files including c2nim files
--debug prints a c2nim stack trace in case of an error
Expand Down
2 changes: 1 addition & 1 deletion c2nim.nimble
@@ -1,4 +1,4 @@
version = "0.9.19"
version = "0.9.20"
author = "Andreas Rumpf"
description = "c2nim is a tool to translate Ansi C code to Nim."
license = "MIT"
Expand Down
10 changes: 10 additions & 0 deletions cparser.nim
Expand Up @@ -58,6 +58,7 @@ type
pfCppSpecialization, ## parse c++ template specializations
pfCppSkipConverter ## skip C++ converters
pfCppSkipCallOp ## skip C++ converters
pfCppBindStatic ## bind cpp static methods to types

Macro* = object
name*: string
Expand Down Expand Up @@ -208,6 +209,7 @@ proc setOption*(parserOptions: PParserOptions, key: string, val=""): bool =
of "reordercomments": incl(parserOptions.flags, pfReorderComments)
of "reordertypes": incl(parserOptions.flags, pfReorderTypes)
of "mergeblocks": incl(parserOptions.flags, pfMergeBlocks)
of "cppbindstatic": incl(parserOptions.flags, pfCppBindStatic)
of "mergeduplicates": incl(parserOptions.flags, pfMergeDuplicates)
of "cppskipconverter": incl(parserOptions.flags, pfCppSkipConverter)
of "cppspecialization":incl(parserOptions.flags, pfCppSpecialization)
Expand Down Expand Up @@ -3175,6 +3177,14 @@ proc parseMethod(p: var Parser, origName: string, rettyp, pragmas: PNode,
# declare 'this':
thisDef = createThis(p, genericParamsThis)
params.add(thisDef)
elif not isNil(p.currentClass) and pfCppBindStatic in p.options.flags:
# bind to type
var typ = newNodeP(nkIdentDefs, p)
var t = newNodeP(nkCommand, p)
t.add(newIdentNodeP("type", p))
t.add(p.currentClass.applyGenericParams(genericParamsThis))
addSon(typ, newIdentNodeP("_", p), t, emptyNode)
params.add(typ)

parseFormalParams(p, params, pragmas)
if p.tok.xkind == pxSymbol and p.tok.s == "const":
Expand Down
27 changes: 27 additions & 0 deletions doc/c2nim.rst
Expand Up @@ -585,6 +585,33 @@ not nested since the ``|}`` doesn't have to be on a line of its own:
#define foobar {| 5 or 9 |}
C++ static method binding
=========================

With ``--cppBindStatic``, C++ static methods will be bound to their types
when possible:

.. code-block:: C++

class ClassA
{
public:
static void hello();
};

Produces for ``hello``:

.. code-block:: Nim
proc hello*(_: type ClassA)
# which can be called like in CPP:
ClassA.hello()
# For static methods outside of classes, or when
# --cppBindStatic is not present:
proc hello*()
hello()
Limitations
Expand Down
20 changes: 20 additions & 0 deletions testsuite/results/cppstatic.nim
@@ -0,0 +1,20 @@
type
ClassA* {.importcpp: "ClassA", header: "cppstatic.hpp", bycopy.} = object


proc test*(_: `type` ClassA) {.importcpp: "ClassA::test(@)",
header: "cppstatic.hpp".}
type
ClassB* {.importcpp: "ClassB", header: "cppstatic.hpp", bycopy.} = object


proc test*(_: `type` ClassB) {.importcpp: "ClassB::test(@)",
header: "cppstatic.hpp".}
type
ClassGeneric*[T] {.importcpp: "ClassGeneric<\'0>", header: "cppstatic.hpp",
bycopy.} = object


proc test*[T](_: `type` ClassGeneric[T]) {.importcpp: "ClassGeneric::test(@)",
header: "cppstatic.hpp".}
proc test*() {.importcpp: "test(@)", header: "cppstatic.hpp".}
2 changes: 1 addition & 1 deletion testsuite/tester.nim
Expand Up @@ -8,7 +8,7 @@ const
c2nimCmd = dotslash & "c2nim $#"
cpp2nimCmd = dotslash & "c2nim --cpp $#"
cpp2nimCmdKeepBodies = dotslash & "c2nim --cpp --keepBodies $#"
hpp2nimCmd = dotslash & "c2nim --cpp --header $#"
hpp2nimCmd = dotslash & "c2nim --cpp --header --cppbindstatic $#"
c2nimExtrasCmd = dotslash & "c2nim --stdints --strict --header --reordercomments --mergeblocks --render:reindentlongcomments --def:RCL_PUBLIC='__attribute__ (())' --def:RCL_WARN_UNUSED='__attribute__ (())' --def:'RCL_ALIGNAS(N)=__attribute__((align))' --render:extranewlines $#"
dir = "testsuite/"
usage = """
Expand Down
20 changes: 20 additions & 0 deletions testsuite/tests/cppstatic.hpp
@@ -0,0 +1,20 @@
class ClassA
{
public:
static void test();
};

class ClassB
{
public:
static void test();
};

template <typename T>
class ClassGeneric
{
public:
static void test();
};

static void test();

0 comments on commit e65f463

Please sign in to comment.