Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2013-03

RTTI for ProcVar types

12 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Steve Hildebrandt

Hi,

since i needed RTTI for ProcVar types i just added this to the compiler. Following example works just fine :

uses typinfo;
type TFoo = procedure(bar : byte) of object;
var pInfo : PTypeInfo;
      pData : PTypeData;
begin
    pInfo := TypeInfo(TFOO);
    pData := GetTypeData(pInfo);
    with pInfo^ do
      writeln('Kind: ', kind, ' Name: ', name);
    with pData^ do
      writeln('MethodKind: ', MethodKind, ' ParamCount: ', ParamCount);
    readln;
end.

The only problem, that has occured is projects using JPEGLIB produce the following errors :
Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF104
Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF150

Any ideas what could cause this? (I only modified ncrtti.pas and typeinfo.pp)

mfg Necem

Reply by email

Sven Barth
to Steve Hildebrandt
Steve Hildebrandt wrote
since i needed RTTI for ProcVar types i just added this to the compiler.

Out of curiosity: Why did you add this?

Show quoted text 7 lines
The only problem, that has occured is projects using JPEGLIB produce the following errors : Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF104 Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF150 Any ideas what could cause this? (I only modified ncrtti.pas and typeinfo.pp)

Without you showing what you changed we can not help much...

Regards,
Sven

Reply by email

Steve Hildebrandt
to Sven Barth
Sven Barth wrote
Out of curiosity: Why did you add this?

To implement a less "hacky" way of generic method invokation. Supporting several calling conventions I can call a method based on the address and an array of const as parameters.
Without RTTI there would've been a need for hard coded meta information, wich is error prone and rather time consuming.
Since tkMethod supports RTTI any method contained in a record, class, object would work without additional meta information. I'm currently using this to call pascal procedures and use pascal classes in LUA.

Without you showing what you changed we can not help much...

typinfo.pp :
tkMethod, tkProcVar: // simply added tkProcVar here

               (MethodKind : TMethodKind;
                ParamCount : Byte;
                ParamList : array[0..1023] of Char

ncgrtti.pas:(Line 690)
procedure procvardef_rtti(def:tprocvardef);
...
begin
{ write method id and name }
if po_methodpointer in def.procoptions
then write_header(def,tkMethod)

     else write_header(def,tkProcVar);
   maybe_write_align;
   ...

So that RTTI generation for tkProcVar and tkMethod would only differentiate in the TTypeKind field.

mfg Necem

Reply by email

Sven Barth
to Steve Hildebrandt
Steve Hildebrandt wrote 9 lines
Am 21.03.2013 11:51, schrieb Sven Barth: > Out of curiosity: Why did you add this? To implement a less "hacky" way of generic method invokation. Supporting several calling conventions I can call a method based on the address and an array of const as parameters. Without RTTI there would've been a need for hard coded meta information, wich is error prone and rather time consuming. Since tkMethod supports RTTI any method contained in a record, class, object would work without additional meta information.

Out of interest: do you support multiple platforms? Maybe if you want to provide your code under modified LGPL we could use it once we have the RTTI.TValue type and the extended RTTI to support RTTI.Invoke.

Show quoted text 21 lines
I'm currently using this to call pascal procedures and use pascal classes in LUA. > Without you showing what you changed we can not help much... typinfo.pp : tkMethod, tkProcVar: // simply added tkProcVar here (MethodKind : TMethodKind; ParamCount : Byte; ParamList : array[0..1023] of Char ncgrtti.pas:(Line 690) procedure procvardef_rtti(def:tprocvardef); ... begin { write method id and name } if po_methodpointer in def.procoptions then write_header(def,tkMethod) else write_header(def,tkProcVar); maybe_write_align; ... So that RTTI generation for tkProcVar and tkMethod would only differentiate in the TTypeKind field.

I can reproduce your problem, but I don't have a solution. At least it is enough to only use that unit, so you could copy the unit locally and comment everything until the problem disappears. This way you could pinpoint what construct the problem is and then try to fix the compiler. And if it then works without further problems we could add this to trunk.

Regards,
Sven

Reply by email

Steve Hildebrandt
to Sven Barth
Sven Barth wrote 14 lines
On 21.03.2013 15:53, Steve Hildebrandt wrote: > Am 21.03.2013 11:51, schrieb Sven Barth: >> Out of curiosity: Why did you add this? > To implement a less "hacky" way of generic method invokation. > Supporting several calling conventions I can call a method based on the > address and an array of const as parameters. > Without RTTI there would've been a need for hard coded meta information, > wich is error prone and rather time consuming. > Since tkMethod supports RTTI any method contained in a record, class, > object would work without additional meta information. Out of interest: do you support multiple platforms? Maybe if you want to provide your code under modified LGPL we could use it once we have the RTTI.TValue type and the extended RTTI to support RTTI.Invoke.

Sure i can provide the code. Some modifications would be needed, so it is easier to adopt it to RTTI.Invoke.
Regarding the platforms:
Calling conventions 64bit : win64(the microsoft standart thing dunno how its called right now)
32bit : stdcall, register.
Since the inline asm code for the actual call differs depending on witch registers are used,
this part can't be handled in a generic way and needs to be coded down for each convention.
While passing parameters on the Stack works rather generic(well obtaining the stack pointer is the exception here). Calculation of the stack offset/used register too is dependant on the convention.
Hope this sums up what needs to be done to port the approach I took to all platforms supported.

Show quoted text 28 lines
> I'm currently using this to call pascal procedures and use pascal > classes in LUA. >> Without you showing what you changed we can not help much... > typinfo.pp : > tkMethod, tkProcVar: // simply added tkProcVar here > (MethodKind : TMethodKind; > ParamCount : Byte; > ParamList : array[0..1023] of Char > ncgrtti.pas:(Line 690) > procedure procvardef_rtti(def:tprocvardef); > ... > begin > { write method id and name } > if po_methodpointer in def.procoptions > then write_header(def,tkMethod) > else write_header(def,tkProcVar); > maybe_write_align; > ... > > So that RTTI generation for tkProcVar and tkMethod would only > differentiate in the TTypeKind field. I can reproduce your problem, but I don't have a solution. At least it is enough to only use that unit, so you could copy the unit locally and comment everything until the problem disappears. This way you could pinpoint what construct the problem is and then try to fix the compiler. And if it then works without further problems we could add this to trunk.
Narrowed it down to those 2 records :
type
   jpeg_entropy_encoder = record
     //test.lpr(23,1) Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF2
     //ORIGINAL JPEGLib Line 539
     //parameter MCU_data leads to the error
     encode_mcu : function({cinfo : Pointer; }const MCU_data : array of
Pointer) : boolean;
   end;
   jpeg_entropy_decoder = record
     //test.lpr(23,1) Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF5
     //ORIGINAL JPEGLib Line 655
     //parameter MCU_data leads to the error
     decode_mcu : function({cinfo : Pointer; }var MCU_data : array of
Pointer) : boolean;
   end;
But here I'm lost again.

mfg Necem

Reply by email

Sven Barth
to Steve Hildebrandt
Steve Hildebrandt wrote 32 lines
Am 21.03.2013 22:00, schrieb Sven Barth: > On 21.03.2013 15:53, Steve Hildebrandt wrote: >> Am 21.03.2013 11:51, schrieb Sven Barth: >>> Out of curiosity: Why did you add this? >> To implement a less "hacky" way of generic method invokation. >> Supporting several calling conventions I can call a method based on the >> address and an array of const as parameters. >> Without RTTI there would've been a need for hard coded meta >> information, >> wich is error prone and rather time consuming. >> Since tkMethod supports RTTI any method contained in a record, class, >> object would work without additional meta information. > > Out of interest: do you support multiple platforms? Maybe if you want > to provide your code under modified LGPL we could use it once we have > the RTTI.TValue type and the extended RTTI to support RTTI.Invoke. Sure i can provide the code. Some modifications would be needed, so it is easier to adopt it to RTTI.Invoke. Regarding the platforms: Calling conventions 64bit : win64(the microsoft standart thing dunno how its called right now) 32bit : stdcall, register. Since the inline asm code for the actual call differs depending on witch registers are used, this part can't be handled in a generic way and needs to be coded down for each convention. While passing parameters on the Stack works rather generic(well obtaining the stack pointer is the exception here). Calculation of the stack offset/used register too is dependant on the convention. Hope this sums up what needs to be done to port the approach I took to all platforms supported.

My idea for the extended RTTI was to let the compiler write out all necessary information for parameter setting (and also retrieval for TVirtualMethodInterceptor support) and then use some kind of mini-meta assembly language to generate the final code.

Regarding the stack pointer:
http://www.freepascal.org/docs-html/rtl/system/sptr.html

Show quoted text 46 lines
>> I'm currently using this to call pascal procedures and use pascal >> classes in LUA. >>> Without you showing what you changed we can not help much... >> typinfo.pp : >> tkMethod, tkProcVar: // simply added tkProcVar here >> (MethodKind : TMethodKind; >> ParamCount : Byte; >> ParamList : array[0..1023] of Char >> ncgrtti.pas:(Line 690) >> procedure procvardef_rtti(def:tprocvardef); >> ... >> begin >> { write method id and name } >> if po_methodpointer in def.procoptions >> then write_header(def,tkMethod) >> else write_header(def,tkProcVar); >> maybe_write_align; >> ... >> >> So that RTTI generation for tkProcVar and tkMethod would only >> differentiate in the TTypeKind field. > > I can reproduce your problem, but I don't have a solution. At least > it is enough to only use that unit, so you could copy the unit > locally and comment everything until the problem disappears. This way > you could pinpoint what construct the problem is and then try to fix > the compiler. And if it then works without further problems we could > add this to trunk. Narrowed it down to those 2 records : type jpeg_entropy_encoder = record //test.lpr(23,1) Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF2 //ORIGINAL JPEGLib Line 539 //parameter MCU_data leads to the error encode_mcu : function({cinfo : Pointer; }const MCU_data : array of Pointer) : boolean; end; jpeg_entropy_decoder = record //test.lpr(23,1) Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF5 //ORIGINAL JPEGLib Line 655 //parameter MCU_data leads to the error decode_mcu : function({cinfo : Pointer; }var MCU_data : array of Pointer) : boolean; end; But here I'm lost again.

Seems to be either related to the const/var, the open array (maybe the hidden high parameter?) or a combination of both.

You could try to debug the compiler. Simply copy the above records to a program unit, load the pp.lpi (or ppcx64.lpi for 64-bit), set up the run parameters and the working directory correctly (if you don't have a correct configuration for 2.7.1 you should use "-n -Fu..." to find the correct RTL units) and then place breakpoints in ncgrtti to check whether the correct data is generated.

Regards,
Sven

Regards,
Sven

Reply by email

Steve Hildebrandt
to Sven Barth
Sven Barth wrote 39 lines
Am 22.03.2013 12:43, schrieb Steve Hildebrandt: > Am 21.03.2013 22:00, schrieb Sven Barth: >> On 21.03.2013 15:53, Steve Hildebrandt wrote: >>> Am 21.03.2013 11:51, schrieb Sven Barth: >>>> Out of curiosity: Why did you add this? >>> To implement a less "hacky" way of generic method invokation. >>> Supporting several calling conventions I can call a method based on >>> the >>> address and an array of const as parameters. >>> Without RTTI there would've been a need for hard coded meta >>> information, >>> wich is error prone and rather time consuming. >>> Since tkMethod supports RTTI any method contained in a record, class, >>> object would work without additional meta information. >> >> Out of interest: do you support multiple platforms? Maybe if you >> want to provide your code under modified LGPL we could use it once >> we have the RTTI.TValue type and the extended RTTI to support >> RTTI.Invoke. > Sure i can provide the code. Some modifications would be needed, so > it is easier to adopt it to RTTI.Invoke. > Regarding the platforms: > Calling conventions 64bit : win64(the microsoft standart thing > dunno how its called right now) > 32bit : stdcall, register. > Since the inline asm code for the actual call differs depending > on witch registers are used, > this part can't be handled in a generic way and needs to be coded > down for each convention. > While passing parameters on the Stack works rather generic(well > obtaining the stack pointer is the exception here). > Calculation of the stack offset/used register too is dependant > on the convention. > Hope this sums up what needs to be done to port the approach I took > to all platforms supported. My idea for the extended RTTI was to let the compiler write out all necessary information for parameter setting (and also retrieval for TVirtualMethodInterceptor support) and then use some kind of mini-meta assembly language to generate the final code.

The questing is what is harder to maintain a meta assembly or some asm snippets doing the calls and managing the stack.

I did look into the sptr function but either I failed to describe what I need or sptr works in weird ways on win64.
I have the following pice of code the get to the offset of the first parameter that will be push :
// stackSize includes $20 for the shadow space and $08 for the method address since the stack should be 16bit aligned
asm (INTEL ASM)
SUB RSP, stackSize
MOV stackPtr, RSP

     end;
     // Skip shadow space to obtain the offset
     stackPtr += $20;
Now if i replace this code with sptr like this :
     asm (INTEL ASM)
       SUB RSP, stackSize // needs to be done so the called method
obtains a correct value from RSP
       //MOV stackPtr, RSP
     end;
     stackPtr := sptr;
     // Skip shadow space to obtain the offset
     stackPtr += $20;

I end up with different values while the first one works for my test cases the second one fails miserably.
Also I think using sptr won't do me much good, since I can't replace all platform dependant code with operations based one sptr. (e.g. implementing the skipping of the shadow space, or reserving space on the stack).

Show quoted text 55 lines
>>> I'm currently using this to call pascal procedures and use pascal >>> classes in LUA. >>>> Without you showing what you changed we can not help much... >>> typinfo.pp : >>> tkMethod, tkProcVar: // simply added tkProcVar here >>> (MethodKind : TMethodKind; >>> ParamCount : Byte; >>> ParamList : array[0..1023] of Char >>> ncgrtti.pas:(Line 690) >>> procedure procvardef_rtti(def:tprocvardef); >>> ... >>> begin >>> { write method id and name } >>> if po_methodpointer in def.procoptions >>> then write_header(def,tkMethod) >>> else write_header(def,tkProcVar); >>> maybe_write_align; >>> ... >>> >>> So that RTTI generation for tkProcVar and tkMethod would only >>> differentiate in the TTypeKind field. >> >> I can reproduce your problem, but I don't have a solution. At least >> it is enough to only use that unit, so you could copy the unit >> locally and comment everything until the problem disappears. This >> way you could pinpoint what construct the problem is and then try to >> fix the compiler. And if it then works without further problems we >> could add this to trunk. > Narrowed it down to those 2 records : > type > jpeg_entropy_encoder = record > //test.lpr(23,1) Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF2 > //ORIGINAL JPEGLib Line 539 > //parameter MCU_data leads to the error > encode_mcu : function({cinfo : Pointer; }const MCU_data : array > of Pointer) : boolean; > end; > > jpeg_entropy_decoder = record > //test.lpr(23,1) Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF5 > //ORIGINAL JPEGLib Line 655 > //parameter MCU_data leads to the error > decode_mcu : function({cinfo : Pointer; }var MCU_data : array of > Pointer) : boolean; > end; > But here I'm lost again. Seems to be either related to the const/var, the open array (maybe the hidden high parameter?) or a combination of both. You could try to debug the compiler. Simply copy the above records to a program unit, load the pp.lpi (or ppcx64.lpi for 64-bit), set up the run parameters and the working directory correctly (if you don't have a correct configuration for 2.7.1 you should use "-n -Fu..." to find the correct RTL units) and then place breakpoints in ncgrtti to check whether the correct data is generated.

I fixed the issues I had with the libjpeg. Attached a patch with the changes I made, or should I file an issue in the bugtracker?

mfg Necem

Reply by email

Sven Barth
to Steve Hildebrandt
Steve Hildebrandt wrote 42 lines
Am 22.03.2013 13:19, schrieb Sven Barth: > Am 22.03.2013 12:43, schrieb Steve Hildebrandt: >> Am 21.03.2013 22:00, schrieb Sven Barth: >>> On 21.03.2013 15:53, Steve Hildebrandt wrote: >>>> Am 21.03.2013 11:51, schrieb Sven Barth: >>>>> Out of curiosity: Why did you add this? >>>> To implement a less "hacky" way of generic method invokation. >>>> Supporting several calling conventions I can call a method based on >>>> the >>>> address and an array of const as parameters. >>>> Without RTTI there would've been a need for hard coded meta >>>> information, >>>> wich is error prone and rather time consuming. >>>> Since tkMethod supports RTTI any method contained in a record, class, >>>> object would work without additional meta information. >>> >>> Out of interest: do you support multiple platforms? Maybe if you >>> want to provide your code under modified LGPL we could use it once >>> we have the RTTI.TValue type and the extended RTTI to support >>> RTTI.Invoke. >> Sure i can provide the code. Some modifications would be needed, so >> it is easier to adopt it to RTTI.Invoke. >> Regarding the platforms: >> Calling conventions 64bit : win64(the microsoft standart thing >> dunno how its called right now) >> 32bit : stdcall, register. >> Since the inline asm code for the actual call differs depending >> on witch registers are used, >> this part can't be handled in a generic way and needs to be coded >> down for each convention. >> While passing parameters on the Stack works rather generic(well >> obtaining the stack pointer is the exception here). >> Calculation of the stack offset/used register too is dependant >> on the convention. >> Hope this sums up what needs to be done to port the approach I took >> to all platforms supported. > My idea for the extended RTTI was to let the compiler write out all > necessary information for parameter setting (and also retrieval for > TVirtualMethodInterceptor support) and then use some kind of mini-meta > assembly language to generate the final code. The questing is what is harder to maintain a meta assembly or some asm snippets doing the calls and managing the stack.

I've not yet decided anyway what I would use...

Show quoted text 27 lines
> Regarding the stack pointer: > http://www.freepascal.org/docs-html/rtl/system/sptr.html I did look into the sptr function but either I failed to describe what I need or sptr works in weird ways on win64. I have the following pice of code the get to the offset of the first parameter that will be push : // stackSize includes $20 for the shadow space and $08 for the method address since the stack should be 16bit aligned asm (INTEL ASM) SUB RSP, stackSize MOV stackPtr, RSP end; // Skip shadow space to obtain the offset stackPtr += $20; Now if i replace this code with sptr like this : asm (INTEL ASM) SUB RSP, stackSize // needs to be done so the called method obtains a correct value from RSP //MOV stackPtr, RSP end; stackPtr := sptr; // Skip shadow space to obtain the offset stackPtr += $20; I end up with different values while the first one works for my test cases the second one fails miserably.

Hmm... the problem could be that "inline" does not yet work with assembly functions and thus "sptr" will result in the generation of a call which will add another shadow space to the stack pointer...

Also I think using sptr won't do me much good, since I can't replace all platform dependant code with operations based one sptr. (e.g. implementing the skipping of the shadow space, or reserving space on the stack).

It was worth a try :)

Show quoted text 57 lines
>>>> I'm currently using this to call pascal procedures and use pascal >>>> classes in LUA. >>>>> Without you showing what you changed we can not help much... >>>> typinfo.pp : >>>> tkMethod, tkProcVar: // simply added tkProcVar here >>>> (MethodKind : TMethodKind; >>>> ParamCount : Byte; >>>> ParamList : array[0..1023] of Char >>>> ncgrtti.pas:(Line 690) >>>> procedure procvardef_rtti(def:tprocvardef); >>>> ... >>>> begin >>>> { write method id and name } >>>> if po_methodpointer in def.procoptions >>>> then write_header(def,tkMethod) >>>> else write_header(def,tkProcVar); >>>> maybe_write_align; >>>> ... >>>> >>>> So that RTTI generation for tkProcVar and tkMethod would only >>>> differentiate in the TTypeKind field. >>> >>> I can reproduce your problem, but I don't have a solution. At least >>> it is enough to only use that unit, so you could copy the unit >>> locally and comment everything until the problem disappears. This >>> way you could pinpoint what construct the problem is and then try to >>> fix the compiler. And if it then works without further problems we >>> could add this to trunk. >> Narrowed it down to those 2 records : >> type >> jpeg_entropy_encoder = record >> //test.lpr(23,1) Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF2 >> //ORIGINAL JPEGLib Line 539 >> //parameter MCU_data leads to the error >> encode_mcu : function({cinfo : Pointer; }const MCU_data : array >> of Pointer) : boolean; >> end; >> >> jpeg_entropy_decoder = record >> //test.lpr(23,1) Error: Undefined symbol: RTTI_$JPEGLIB_$$_DEF5 >> //ORIGINAL JPEGLib Line 655 >> //parameter MCU_data leads to the error >> decode_mcu : function({cinfo : Pointer; }var MCU_data : array of >> Pointer) : boolean; >> end; >> But here I'm lost again. > Seems to be either related to the const/var, the open array (maybe the > hidden high parameter?) or a combination of both. > > You could try to debug the compiler. Simply copy the above records to > a program unit, load the pp.lpi (or ppcx64.lpi for 64-bit), set up the > run parameters and the working directory correctly (if you don't have > a correct configuration for 2.7.1 you should use "-n -Fu..." to find > the correct RTL units) and then place breakpoints in ncgrtti to check > whether the correct data is generated. I fixed the issues I had with the libjpeg. Attached a patch with the changes I made, or should I file an issue in the bugtracker?

Regarding this fix:

+ if po_methodpointer in def.procoptions
+ then write_header(def,tkMethod)
+ else
+ begin
+ write_header(def,tkProcVar);
+ if not (def.owner.symtabletype in [ObjectSymtable, staticsymtable,globalsymtable]) then exit;
+ end;

It might not be the best idea to check def.owner.symtabletype, because we support nested types as well since 2.6.0, e.g:

=== example begin ===

type
   TTest = class
   public type
     TMyProc = procedure;
   end;

=== example end ===

I don't know immediately how you can differentiate between anonymous types and named ones, but that would be the key difference.

Also if you should do a bug report please reformat your patch first, so that it adheres to the compiler's format style (and don't change the formatting of other code like the one in the case except for overall indentation). E.g. for the above code from your patch:

=== example begin ===

if po_methodpointer in def.procoptions then
   write_header(def,tkMethod)
else
   begin
     write_header(def,tkProcVar);
     if not (...) then
       exit;
   end;

=== example end ===

Regards,
Sven

Reply by email

Steve Hildebrandt
to Sven Barth
Sven Barth wrote
I don't know immediately how you can differentiate between anonymous types and named ones, but that would be the key difference.

Since the function building the name usied to access the RTTI table uses only the smytables to decide weather the type is annonymous or referenced by it's name I thought that approach was ok. (symdef.pas 1434)

     function Tstoreddef.rtti_mangledname(rt:trttitype):string;
      ...
         if assigned(typesym) and
            (owner.symtabletype in [staticsymtable,globalsymtable]) then
           result:=make_mangledname(prefix,owner,typesym.name)
         else

result:=make_mangledname(prefix,findunitsymtable(owner),'DEF'+tostr(DefId))

       end;

Or are nested types also referenced by the definition id?(I had something on my mind like Unit Type SubType with some seperators("$") in between)

Also if you should do a bug report please reformat your patch first, so that it adheres to the compiler's format style (and don't change the formatting of other code like the one in the case except for overall indentation). E.g. for the above code from your patch

Is there some template to use with code tools oder some formatter you use.(For this I think I can manage manually but if further issues arrise. It would be better to know if there an easier way to do this^^)

mfg Necem

Reply by email

Sven Barth
to Steve Hildebrandt
Steve Hildebrandt wrote 16 lines
Am 24.03.2013 22:26, schrieb Sven Barth: > I don't know immediately how you can differentiate between anonymous > types and named ones, but that would be the key difference. Since the function building the name usied to access the RTTI table uses only the smytables to decide weather the type is annonymous or referenced by it's name I thought that approach was ok. (symdef.pas 1434) function Tstoreddef.rtti_mangledname(rt:trttitype):string; ... if assigned(typesym) and (owner.symtabletype in [staticsymtable,globalsymtable]) then result:=make_mangledname(prefix,owner,typesym.name) else result:=make_mangledname(prefix,findunitsymtable(owner),'DEF'+tostr(DefId)) end;

Somehow I have the feeling that this should be corrected...

Or are nested types also referenced by the definition id?(I had something on my mind like Unit Type SubType with some seperators("$") in between)

Looking at the code above you could try whether "typesym" of the procvardef is assigned if it is a named one.

Show quoted text 8 lines
> Also if you should do a bug report please reformat your patch first, > so that it adheres to the compiler's format style (and don't change > the formatting of other code like the one in the case except for > overall indentation). E.g. for the above code from your patch Is there some template to use with code tools oder some formatter you use.(For this I think I can manage manually but if further issues arrise. It would be better to know if there an easier way to do this^^)

No, there is none. Also there isn't a completely fixed formatting (yet), because some parts of the compiler are from times where there wasn't a specific formatting yet. I myself am doing the formatting manually, because for my own projects I prefer a different one (that's also why I've reported this Lazarus feature request:
http://bugs.freepascal.org/view.php?id=18517 )

Regards,
Sven

Reply by email

Steve Hildebrandt
to Sven Barth
Show quoted text 19 lines
Am 25.03.2013 10:01, schrieb Sven Barth: > Am 24.03.2013 22:49, schrieb Steve Hildebrandt: >> Am 24.03.2013 22:26, schrieb Sven Barth: >>> I don't know immediately how you can differentiate between >>> anonymous types and named ones, but that would be the key difference. >> Since the function building the name usied to access the RTTI table >> uses only the smytables to decide weather the type is annonymous or >> referenced by it's name I thought that approach was ok. >> (symdef.pas 1434) >> function Tstoreddef.rtti_mangledname(rt:trttitype):string; >> ... >> if assigned(typesym) and >> (owner.symtabletype in [staticsymtable,globalsymtable]) then >> result:=make_mangledname(prefix,owner,typesym.name) >> else >> result:=make_mangledname(prefix,findunitsymtable(owner),'DEF'+tostr(DefId)) >> >> end; > Somehow I have the feeling that this should be corrected...

My knowledge of the wokings of the compiler are not detailed enought to judge or fix this issue.
Shall I report it on the bugtracker?

Show quoted text 5 lines
> Or are nested types also referenced by the definition id?(I had > something on my mind like Unit Type SubType with some seperators("$") > in between) Looking at the code above you could try whether "typesym" of the procvardef is assigned if it is a named one.

Checking for typesym woks fine for my test and use cases.

Reply by email

Sven Barth
to Steve Hildebrandt
Steve Hildebrandt wrote 21 lines
> Am 25.03.2013 10:01, schrieb Sven Barth: >> Am 24.03.2013 22:49, schrieb Steve Hildebrandt: >>> Am 24.03.2013 22:26, schrieb Sven Barth: >>>> I don't know immediately how you can differentiate between >>>> anonymous types and named ones, but that would be the key difference. >>> Since the function building the name usied to access the RTTI table >>> uses only the smytables to decide weather the type is annonymous or >>> referenced by it's name I thought that approach was ok. >>> (symdef.pas 1434) >>> function Tstoreddef.rtti_mangledname(rt:trttitype):string; >>> ... >>> if assigned(typesym) and >>> (owner.symtabletype in [staticsymtable,globalsymtable]) then >>> result:=make_mangledname(prefix,owner,typesym.name) >>> else >>> result:=make_mangledname(prefix,findunitsymtable(owner),'DEF'+tostr(DefId)) >>> >>> end; >> Somehow I have the feeling that this should be corrected... My knowledge of the wokings of the compiler are not detailed enought to judge or fix this issue.

I didn't want to imply that you should do it :)

Shall I report it on the bugtracker?

I don't see a need. It's not a real bug, just not nice... I'll likely correct it myself sometime...

Show quoted text 6 lines
>> Or are nested types also referenced by the definition id?(I had >> something on my mind like Unit Type SubType with some seperators("$") >> in between) > Looking at the code above you could try whether "typesym" of the > procvardef is assigned if it is a named one. Checking for typesym woks fine for my test and use cases.

Ok, now if you'd be so kind to "revert" the formatting changes to the case-block (with exception of the indentation of the whole block) it would be nice if you'd open a feature request with your patch and preferrably together with one or more test cases (only simple ones with as less dependencies as possible, please). I personally am rather sure that we'll include it then :)

Regards,
Sven

Reply by email