[fpc-devel]Again about calling conventions and name mangling

Michael Van Canneyt michael.vancanneyt at wisa.be
Thu Oct 18 12:26:33 CEST 2001

On Thu, 18 Oct 2001, Pavel V. Ozerski wrote:

> Hello Peter and all FPC team,
> Did you look at my $calling patch?

I think the problem is that both Peter and Florian are at this time very
busy, and have not yet had the opportunity to look at it.

> Maybe, I should fix or improve something in it? Or you needs some my
> commentaries?
> Btw, I'm not sure that general parsing of procedure directives in FPC
> is good. There are exist also some differences between FPC and Delphi.
> This example can be compiled with Delphi 3 but not with FPC:
> {$ifdef fpc}
> {$mode delphi}
> {$endif}
> procedure X(x1,x2:longint);stdcall;cdecl;pascal;
>  begin
>  end;
> begin
>  X(1,2);
> end.
> FPC 1.1 gives an error message:
> test.pp(4,42) Error: Procedure directive "PASCAL" has conflicts with other directives
> test.pp(4,42) Fatal: Syntax error, "BEGIN" expected but "identifier PASCAL" found
> Delphi 3 compiles this sample successfully, I assume that last calling
> convention directive overlaps all previous.

But it is an error nevertheless, you should specify only 1 calling convention.
It's just an error in Delphi; Look in the help:

"When you declare a procedure or function, you can specify a calling convention
using one of the directives register, pascal, cdecl, stdcall, and safecall. For example,"

it says clearly: using one !

> I think, Delphi behavior must at least be supported in $delphi mode of
> FPC.

I don't agree, I think it is an error in the Delphi parser.

> Additionally, I think, procedure directives must be sorted into
> groups to simplify and improve solving conflicts and overlapping.
> I suggest:
> 1) introduce new type tProcDirKind=(pdk_Mangling, pdk_CallConv... etc;
> 2) add to proc_dir_rec type (unit pdecsub.pas) a new field, kind:
> tProcDirKind;
> 3) differently check conflicts between directives for every kind;
> 4) separate handling of calling conventions from handling of name
> mangling. This solution can seem to be painful, because can disturb
> compatibility with older FPC versions, but I think, it is necessary.
> New keywords like "cmangled", "cppmangled" etc must be introduced,
> default using of calling conventions-related directives must cause no
> changes in names mangling. Btw, relationships between name mangling and
> calling conventions is not only strange but also somewhere wrong now. For
> example, function TheFunc(x1:pchar;x2:longint):longint;stdcall;
> now will be mangled in FPC to _THEFUNC$PCHAR$LONGINT but C/C++
> compilers will mangle this stdcall function to _TheFunc at 8 .
> That's not logical, to emulate C/C++ name mangling only for a part of common
> calling conventions!

Nevertheless, If I remember correctly, the Delphi/Kylix compiler does the
same as FPC in this area. On linux, 'cdecl' also mangles the name.

> Another problem which is caused with the unasked name mangling
> changes: A small demo which includes 2 units and one program which
> used these units:
> unit unit1;
> interface
> procedure test(x:longint);cdecl;
> implementation
> procedure test(x:longint);cdecl;
>  begin
>   writeln('1:',x);
>  end;
> end.
> unit unit2;
> interface
> procedure test(x:longint);cdecl;
> implementation
> procedure test(x:longint);cdecl;
>  begin
>   writeln('2:',x);
>  end;
> end.
> program main;
> uses
>  unit1,unit2;
> begin
>  unit1.test(100);
>  unit2.test(100);
> end.
> Try to build this project without changes in sources!
> I got problems at linking stage because both cdecl procedures in
> different units have the same mangled name! This example demonstrates
> that non-FPC name mangling must be used very carefully, but now it is
> applying in very common cases.

But it is clearly stated in the documentation that this will happen, so
you have been warned.

>  Btw, IMHO, even if the "automatic"
> C-like name mangling would be excluded from FPC, the compiler became
> not very less flexible because there are exist also syntax constructions
> like
> procedure TheProc(x1:pchar);stdcall;external name '_TheProc at 4';
> for import and
> procedure TheProc(x1:pchar);stdcall;[public,alias:'_TheProc at 4'];
> for export.
> I could also try to solve some these problems but I could know the
> lot of my $calling patch, because solving ways depend on it.

I am not sure which course should be followed; I am inclined to leave it
as it is; As long as every effect of the directives is clearly documented,
I do not see any reason to change it.

What would be a good thing is to split the implementation in the compiler
into a name-mangling part and calling convention part, as you suggest, se
specifying a directive sets 2 variables: One specifycing the name mangling,
and one specifying the calling convention. It will definitely improve the
compiler's internal workings.

But you should try and wait for an answer of Peter or Florian, as they
are mostly the experts in this area.


More information about the fpc-devel mailing list