Recent Posts

Pages: [1] 2 3 ... 10
Implementation Details / Rebased on clang-60
« Last post by bas on March 28, 2018, 08:43:13 PM »
C2C is now based on LLVM/Clang 6.0. The port was rather easy and took 20 minutes (excluding time to build LLVM/Clang).
The only nasty thing was a shift in arguments in include/clang/Basic/DiagnosticSemaKinds.def. This gives runtime asserts,
but luckily one of the unit tests broke, so it was very easy to detect and locate.

The performance seems to be the same and I've noticed no other differences. The clang binary does seem to have grown
another 5MB (87 -> 92 MB), all nice features I'm sure ;)
Implementation Details / cross-compilation using build file
« Last post by bas on March 22, 2018, 10:27:54 PM »
I've recently added the concept of a build file to C2. I would like to explain some design choices here.

The C2 compiler used to use a single configuration file called the recipe. The recipe describes:
  • which targets and type (executable or library
  • which source files for each target
  • the configuration options
  • some output options (whether to generate-c, deps, refs, etc)
  • which libraries the targets depend on
So the recipe only specifies which dependencies, not where to find them. Because C2 is also meant
for embedded systems where cross-compilation is a basic need, it should be easy to do. To handle
this, there now is a build file that specifies:
  • The target triple (eg arm-unknown-linux-gnueabi or x86_64-unknown-linux-gnu)
  • A list of library search directories
  • toolchain settings for the C-backend
When using a build file, C2C will only use paths from that build file. This makes it trivial
to isolate cross-builds between different targets. No need for sysroot like constructs.

The general idea is that the recipe file is written by the develops of the project. If the project has a lot
of configuration options (which could change the files that need to be compiled), a 'make menuconfig'
like tool could generate this.

The build file is either written by users or generated by a 3rd party build system like yocto/buildroot etc
The same recipe could be used to build for different targets by using a different build file for each.

To demonstrate this, the C2-examples archive has a working example for Ubuntu 17.04. See the
for instructions.

Future work
Currently C2 uses a <triple> subdirectory in each library directory, so it can hold libraries for multiple targets.
This is handy for now, but in a real system, an (external) build system will already have populated a sysroot-like
directory with all required libs. So this directory will be removed in the future.

Another step will be to add a Cargo-like (from Rust) tool that reads the recipe, downloads all required libraries and
generates the build file.

Cross-compilation for ansi-C is quire a hassle. Hopefully C2 can make this a lot easier.
For more documentation see

As always, other ideas/feedback is welcome.
Ideas / Re: Struct Function declaration
« Last post by magnusi on May 09, 2017, 07:40:09 PM »
how about something like this?
Code: [Select]
func[Point]  void add(self, int32 x) { .. } // add the type to the func keyword, replace replace the instance with self
structfunc void add(Point* p, int32 x) { .. } // just say it's a struct func

The last option was also nice

suggestion No.3:
Code: [Select]
func void add(self*, int32 x) for Point { .. } // variation 1
func void add(Point* self, int32 x) for Point { .. } // variation 2
Ideas / Struct Function declaration
« Last post by bas on April 15, 2017, 09:22:04 PM »
With the current syntax, I think it's quite unclear when a function is a struct function. I would
like to try to make this more explicit. So hereby some ideas.

Code: [Select]
func void point_add(Point* p, int32 x) { .. }    // current syntax

func void Point_add(Point* p, int32 x) { .. }   // allow Upper-case as first char, so looks more like type Point

func void point_add[Point](Point* p, int32 x) { ..} /// hmm, 3 points in a

func void point_add(Point* p, int32 x) @{structfunc} { ..} // via attribute
func void point_add(Point* p, int32 x) @{struct='Point'} { ..} // via attribute, nr 2

func void Point.add(Point* p, int32 x) { .. }   // most explicit, via member operator


I like the last option best. The two arguments against it are:
  • it's harder to see what the c- function name is (point_add in all cases). The is actually currently
        the same for module attributes as well ( -> foo_bar)
  • The syntax breaks more with the ansiC style

What do you think?
General Discussion / Re: VLA crash
« Last post by bas on March 15, 2017, 08:37:44 AM »
The issue reproduces nicely indeed. There seem to be several issues here. The first one
is that array subscript expressions were not marked at compile-time-constant (if they were).
That is fixed on a branch now. Since C2 allows more then C sometimes, I'll look carefully
at the order of evaluation, since it's otherwise easy to get loops in constant declarations
that we have to detect/avoid..
General Discussion / Re: Diffs to C99 and C11
« Last post by admin on March 13, 2017, 08:05:37 AM »
Since C2 uses the clang preprocessor, all normal C preprocessor command should work. This is more a by-effect than
a real  design target..
General Discussion / Re: VLA crash
« Last post by admin on March 13, 2017, 08:04:29 AM »
Good one!
I'll turn it into a unit test and fix it this evening..
General Discussion / VLA crash
« Last post by shiv on March 08, 2017, 04:59:55 AM »
The following code:

module test;
import stdio;
public func int32 main () {
   const uint64[2] Dims = {2, 3}
   float32[Dims[0]][Dims[1]] p;
   p[0][0] = 1;
   p[0][1] = 2;
   stdio.printf ("%g %g", p[0][0], p[0][1]);
  return 0;

causes the following error:
c2c: /home/shiv/c2compiler/c2c/CGenerator/CCodeGenerator.cpp:485: void C2::CCodeGenerator::EmitDecl(const C2::Decl *, C2::StringBuilder &): Assertion `D' failed.
Aborted (core dumped)

Not sure what Assert 'D' is?
General Discussion / Re: Diffs to C99 and C11
« Last post by shiv on March 07, 2017, 12:14:54 AM »
Looking through the source I see that "#define" is allowed. I also tried and noticed that "#include" is allowed too. Just with those two I can get some of functor like generics that I need.
General Discussion / Re: Complex numbers
« Last post by shiv on March 07, 2017, 12:03:09 AM »
In the standard (assuming we include complex.h) only "float/double complex" are allowed. GNU also allows "int complex".
All the arithmetic operators *,+,- are overloaded and ~ means complex conjugation.
If we include tgmath.h then we also get "generic" math functions like sin(), cos(), etc. So, it is actually quite nice!

I wonder if in c2 you should follow Rust's example and have separate modules named float32, float64, complex32, complex64, etc.,
and hide the functions inside each module. That way we could avoid names like sin, sinf, sinc, sinz, etc..

Not sure how to call C macros from C2; otherwise there might be another route though that might not work if you target llvm-ir (?) directly.

Pages: [1] 2 3 ... 10