Question about nested types and name mangling

General FreeBASIC programming questions.
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Question about nested types and name mangling

Post by angros47 »

As far as I know, FreeBasic doesn't allow to declare a type inside a type, but allows to use a type previously declared. So, a structure that in C would look like

Code: Select all

struct UDT{
    struct internalFormat{
        int a;
        int b;
    } internalData;
    int c;
}
should be converted to something like:

Code: Select all

type internalFormat
  a as long
  b as long
end type

type UDT
  internalData as internalFormat
  int c
end type
This would work fine while interfacing FreeBasic with C (internally, the two structures are perfectly equivalent, if declared with 'extern "c" ' )

Unfortunately, I just realized that such approach doesn't work while interfacing with code written in C++. In fact, if I have a function (for example a class member) that has a parameter of "internalFormat" type, it cannot be called from FreeBasic: the reason is that the type name is included in the function name mangled, to allow overloading, and the name of internalFormat, in the C++ code, is "UDT::internalFormat", since the type has been declared inside the type UDT. In FreeBasic, the name is just "internalFormat", and as result the linker returns an error.

So, my question is: is there a way to force the type "internalFormat" to be seen as "UDT::internalFormat", by the compiler? Otherwise, the only alternative I can figure is to manually access the mangled function name (that is very ugly to see and to declare, and makes the code prone to bugs). Also, I am trying to get rid of any sort of C wrappers, so making a wrapper is not an option.
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Question about nested types and name mangling

Post by angros47 »

No clues?
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Question about nested types and name mangling

Post by angros47 »

In the compiler source, in the file symb-mangling.bas, I see the code:

Code: Select all

        if( docpp ) then
		'' nested? (namespace or class)
		if( hIsNested( sym ) ) then
			mangled += "E"
		end if
	end if
in two spots. It makes me think that there is some way to tell that a class/struct is nested inside another, but how?
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Question about nested types and name mangling

Post by angros47 »

angros47 wrote:In the compiler source, in the file symb-mangling.bas, I see the code:

Code: Select all

	if( docpp ) then
		'' nested? (namespace or class)
		if( hIsNested( sym ) ) then
			mangled += "E"
		end if
	end if
in two spots. It makes me think that there is some way to tell that a class/struct is nested inside another, but how?
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Question about nested types and name mangling

Post by coderJeff »

angros47 wrote:So, my question is: is there a way to force the type "internalFormat" to be seen as "UDT::internalFormat", by the compiler?
I think the short answer is that it is not possible to force in any reasonable way. It would require fbc to see the name "internalFormat" as a member of "UDT", but UDT doesn't exist at the time of declaration of "internalFormat"

fbc doesn't support named nested types (neither in the parser nor the symbol database). Even though a TYPE is kind of like a namespace the parsing and name lookups aren't quite handled the same way. So, I think looking at a number of internal changes to support this.

When fbc computes the mangled name it's based only on the information stored in the symbol table.

I think, the effort would need to be made much earlier in the parser to allow named nested types and storing the required information in the symbol database, so that later when member lookups are made and name mangling is calculated, there's enough information to get what you want.
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Question about nested types and name mangling

Post by angros47 »

I see. So, imagine that the class UDT had a member like

Code: Select all

void foo(internalFormat x);
declaring it with:

Code: Select all

declare sub foo(x as internalFormat)
in FreeBasic doesn't work. The only way would be to make a routine that calls the C mangled name and passes both "@this" and "x"? There isn't a better way?
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Question about nested types and name mangling

Post by coderJeff »

angros47 wrote:There isn't a better way?

Code: Select all

extern "c++"
	namespace nsUDT alias "UDT"
		type internalFormat
		  a as long
		  b as long
		end type
	end namespace
	
	type UDT '' [alias "UDT"]
	  internalData as nsUDT.internalFormat
	  dim as long c
	  declare sub foo(x as nsUDT.internalFormat)
	end type
	
end extern

dim as UDT x
dim as nsUDT.internalFormat y

x.foo( y )
I forgot can do ALIAS on NAMESPACE, TYPE, UNION, ENUM.
On the fbc side different symbol names are needed because fbc doesn't know how to do it any other way.

But, by using ALIAS the NAMESPACE and TYPE can be combined on the c++ side through the name mangling.
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Question about nested types and name mangling

Post by angros47 »

Thank you, but unfortunately, it didn't work.

Specifically, the mangled name produced by the C++ compiler is: _ZN3UDT3fooENS_14internalFormatE

The mangled name produced by FreeBasic in my example is: _ZN3UDT3fooER14internalFormat
The mangled name produced by FreeBasic in your example (adding the namespace) is : _ZN3UDT3fooERN3UDT14internalFormatE

So, closer.... but still not right
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Question about nested types and name mangling

Post by coderJeff »

angros47 wrote:Thank you, but unfortunately, it didn't work.
A parent / child association needs to be made between the 2 types. I didn't find any clever way to force or override with just alias.
I can tell from the mangled name that the type should be passed byval.

What can't be known from the mangled name alone is if the member is static or non-static (taking a hidden this parameter). So need to be careful on that.
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Question about nested types and name mangling

Post by angros47 »

Even adding the byval keyword doesn't help. So... I have no other choice than using the "ugly" mangled name?

About the member being static or non-static, that's actually irrelevant. In fact, there might be no "internalData" member at all, since the mangling is just about the x parameter of the foo method. You can remove the internalData member from the example, nothing should change
Vortex
Posts: 118
Joined: Sep 19, 2005 9:50

Re: Question about nested types and name mangling

Post by Vortex »

Hi angros47,

Maybe not a good solution but do you have the chance to replace the decorated symbol name in your object module using Agner Fog's objconv tool?

Code: Select all

-nr:N1:N2  Replace symbol Name N1 with N2.
-np:N1:N2  Replace symbol Prefix N1 with N2.
-ns:N1:N2  Replace symbol Suffix N1 with N2.
-ar:N1:N2  make Alias N2 for existing public name N1.
-ap:N1:N2  Replace symbol Prefix and keep old name as alias.
-as:N1:N2  Replace symbol Suffix and keep old name as alias.
The option to try :

Code: Select all

-nr:N1:N2  Replace symbol Name N1 with N2.
https://www.agner.org/optimize/
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Question about nested types and name mangling

Post by angros47 »

@Vortex

Interesting idea, but since I wanted to translate a header, your solution would require to repeat that symbol replacement at each recompile, and it wouldn't be an option
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Question about nested types and name mangling

Post by D.J.Peters »

@angros47 some day you will find out why I wrote all the tons of C++ wrappers for FreeBASIC ;-)

Tokamak-c, FLTK-c, Horde3d-c etc.

Joshy
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Question about nested types and name mangling

Post by angros47 »

I guess you missed the last sentence of my first post:
Also, I am trying to get rid of any sort of C wrappers, so making a wrapper is not an option.
I was aware of your wrapper, but my goal was to have a way to use the library FLTK (yes, I knew that there was a wrapper, and I knew you were the author) directly from FreeBasic. Because FreeBasic has much more potential than C, it is closer to C++, and a C wrapper is a bottleneck, in my opinion.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Question about nested types and name mangling

Post by caseih »

No amount of name mangling is going to make FB work completely with all C++ objects. The problem is that FB's object model does not match C++ 1:1 and thus it's really impossible to interface with all C++ classes directly from FB. Simple ones certainly work, provided you avoid multiple inheritance and template classes. For the rest, the only way is to write a wrapper using C++ that exposes a pure C interface. This is true of nearly all other languages as well, when it comes to interoperating with C++ libraries. At least the languages I'm familiar with. C++ is a powerful language, but it certainly does its own thing compared to other popular languages with simpler object models.
Post Reply