Skip to content

Commit

Permalink
misc bugfixes [backport:1.2] (#19203)
Browse files Browse the repository at this point in the history
(cherry picked from commit 23c117a)
  • Loading branch information
Araq authored and narimiran committed Dec 6, 2021
1 parent 0df0510 commit 6d3b706
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 23 deletions.
17 changes: 11 additions & 6 deletions compiler/semobjconstr.nim
Original file line number Diff line number Diff line change
Expand Up @@ -358,12 +358,17 @@ proc defaultConstructionError(c: PContext, t: PType, info: TLineInfo) =
while objType.kind != tyObject:
objType = objType.lastSon
assert objType != nil
var constrCtx = initConstrContext(objType, newNodeI(nkObjConstr, info))
let initResult = semConstructTypeAux(c, constrCtx, {})
assert constrCtx.missingFields.len > 0
localError(c.config, info,
"The $1 type doesn't have a default value. The following fields must be initialized: $2.",
[typeToString(t), listSymbolNames(constrCtx.missingFields)])
if objType.kind == tyObject:
var constrCtx = initConstrContext(objType, newNodeI(nkObjConstr, info))
let initResult = semConstructTypeAux(c, constrCtx, {})
if constrCtx.missingFields.len > 0:
localError(c.config, info,
"The $1 type doesn't have a default value. The following fields must be initialized: $2." % [typeToString(t), listSymbolNames(constrCtx.missingFields)])
elif objType.kind == tyDistinct:
localError(c.config, info,
"The $1 distinct type doesn't have a default value." % typeToString(t))
else:
assert false, "Must not enter here."

proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
var t = semTypeNode(c, n[0], nil)
Expand Down
31 changes: 14 additions & 17 deletions doc/backends.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ The commands to compile to either C, C++ or Objective-C are:
The most significant difference between these commands is that if you look
into the ``nimcache`` directory you will find ``.c``, ``.cpp`` or ``.m``
files, other than that all of them will produce a native binary for your
project. This allows you to take the generated code and place it directly
project. This allows you to take the generated code and place it directly
into a project using any of these languages. Here are some typical command-
line invocations::

Expand Down Expand Up @@ -110,8 +110,8 @@ Nim code calling the backend
Nim code can interface with the backend through the `Foreign function
interface <manual.html#foreign-function-interface>`_ mainly through the
`importc pragma <manual.html#foreign-function-interface-importc-pragma>`_.
The ``importc`` pragma is the *generic* way of making backend symbols available
in Nim and is available in all the target backends (JavaScript too). The C++
The `importc` pragma is the *generic* way of making backend symbols available
in Nim and is available in all the target backends (JavaScript too). The C++
or Objective-C backends have their respective `ImportCpp
<manual.html#implementation-specific-pragmas-importcpp-pragma>`_ and
`ImportObjC <manual.html#implementation-specific-pragmas-importobjc-pragma>`_
Expand Down Expand Up @@ -232,11 +232,6 @@ Also, C code requires you to specify a forward declaration for functions or
the compiler will assume certain types for the return value and parameters
which will likely make your program crash at runtime.

The Nim compiler can generate a C interface header through the ``--header``
command-line switch. The generated header will contain all the exported
symbols and the ``NimMain`` proc which you need to call before any other
Nim code.


Nim invocation example from C
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -255,9 +250,10 @@ Create a ``maths.c`` file with the following content:

.. code-block:: c
#include "fib.h"
#include <stdio.h>
extern int fib(int a);
int main(void)
{
NimMain();
Expand All @@ -270,26 +266,27 @@ Now you can run the following Unix like commands to first generate C sources
from the Nim code, then link them into a static binary along your main C
program::

$ nim c --noMain --noLinking --header:fib.h fib.nim
$ gcc -o m -I$HOME/.cache/nim/fib_d -Ipath/to/nim/lib $HOME/.cache/nim/fib_d/*.c maths.c
.. code:: cmd
nim c --noMain --noLinking fib.nim
gcc -o m -I$HOME/.cache/nim/fib_d -Ipath/to/nim/lib $HOME/.cache/nim/fib_d/*.c maths.c
The first command runs the Nim compiler with three special options to avoid
generating a ``main()`` function in the generated files, avoid linking the
object files into a final binary, and explicitly generate a header file for C
integration. All the generated files are placed into the ``nimcache``
generating a `main()`:c: function in the generated files and to avoid linking the
object files into a final binary. All the generated files are placed into the ``nimcache``
directory. That's why the next command compiles the ``maths.c`` source plus
all the ``.c`` files from ``nimcache``. In addition to this path, you also
have to tell the C compiler where to find Nim's ``nimbase.h`` header file.

Instead of depending on the generation of the individual ``.c`` files you can
also ask the Nim compiler to generate a statically linked library::

$ nim c --app:staticLib --noMain --header fib.nim
$ gcc -o m -Inimcache -Ipath/to/nim/lib libfib.nim.a maths.c
nim c --app:staticLib --noMain fib.nim
gcc -o m -Inimcache -Ipath/to/nim/lib libfib.nim.a maths.c

The Nim compiler will handle linking the source files generated in the
``nimcache`` directory into the ``libfib.nim.a`` static library, which you can
then link into your C program. Note that these commands are generic and will
then link into your C program. Note that these commands are generic and will
vary for each system. For instance, on Linux systems you will likely need to
use ``-ldl`` too to link in required dlopen functionality.

Expand Down

0 comments on commit 6d3b706

Please sign in to comment.