[fpc-devel] C-block reference syntax (blocker for 3.2)

Sven Barth pascaldragon at googlemail.com
Sat Dec 7 19:39:29 CET 2019

Am 07.12.2019 um 14:31 schrieb Blaise at blaise.ru:
>> your argument with VarArgs does not count either: one can not access 
>> VarArgs parameters inside a Delphi function (without resorting to 
>> assembly)
> Again, you are misinformed.
> I understand that you may not use DCC as much or at all, but you have 
> just indicated in an adjacent email that you do have access to it.
> You made the original assumption that DCC does not accept calling 
> convention directives on method references without actually checking 
> or asking someone with DCC experience, and, despite me having 
> indicated twice already that VARARGS is acceptable and works, you 
> continue to argue that it does not. Based on what, if not on your vast 
> DCC experience?

I'm not arguing that DCC supports declaring functions with VARARGS 
directive, but I'm arguing that there is no builtin way to *access* the 
parameters passed in such a way. Yes, there are hacks (like this one 
), but this is not guaranteed to work on every platform. Thus FPC 
explicitely forbids implementing functions that have the varargs 
modifier (they are okay for external functions and also procedure 
variables as the later can point to an external function). This will not 
change with anonymous functions and an anonymous function with varargs 
modifier will not be allowed anyway.

>> So there is no real overlap here.
> The "real overlap here" is that, depending on which $MODESWITCH 
> happens to be in effect, the sequence of lexemes
>     type M = reference to procedure cdecl;
> have different semantics -- constructing different entities that can 
> and should be allowed to coexist, even within a single unit, without 
> the need to toggle $MODESWITCH back and forth.
>> But if we want to change this syntax, we should definitely change 
>> this now before 3.2 is out of the door.
> Jonas just said that he "indeed did not know" about the syntax collision.
> And that baffles me the most. The issue may have gone unnoticed back 
> in 2016, but you were definitely aware of it in 2018. So, back in 
> August, I reasonably assumed that you were presenting the consolidated 
> position of the team. Turns out, you have never brought it to the 
> team, and made that questionable design decision on your own.
> This warrants a discussion, the one I thought the team already had 
> (hence my overly elaborate plea), and now we are blocking 3.2 at the 
> finish line.

I agree that I should have brought this to the team back then, but I 
still stand with my opinion. But if Jonas says that should be changed 
I'll be the last to complain here...

>> Am 07.12.2019 um 01:00 schrieb Blaise at blaise.ru:
>>> Jonas parses them via procvar_dec, and I parse closure reference 
>>> types via parse_proc_dec under 
>>> symtablestack.push(invokable_interface.symtable), and it makes 
>>> perfect sense since such types /are/ interfaces (to the point that 
>>> they are directly implementable on classes).
>> you should parse the declaration using procvar_dec (with possible 
>> extensions/checks) as well, because that handles procvar specific 
>> functionality
> But I do not need the "procvar specific functionality". As I said, I 
> need an interface type, thus it makes perfect sense to parse the 
> declaration as a method header and to get almost everything handled 
> "for free".

You need procvar specific functionality, because you need to restrict 
the available modifiers to those available for procvars. Even if you 
would call parse_var_proc_directives instead of parse_proc_directives or 
parse_object_proc_directives (I don't know what you use right now) the 
parser internally uses check_proc_directives(false) inside 
parse_proc_dec and friends thus you'd get unclean handling if someone 
would use e.g. the "overload" directive which is allowed for interface 
methods, but not for proc-/methodvars.

Also with Jonas' preferred syntax for the cblocks being "reference to 
XXX; cblocks;" you need to use procvar_dec anyway.

>> Only afterwards you create an interface with an appropriate method.
> And what do I do with the unneeded procvardef? :)

You extend tprocvardef.create with a doregister parameter (and pass that 
to the inherited constructor) and set that to False for "reference to" 
types. You then register it for "cblocks" types and for anonymous 
function you convert the procvar to an interface method and then free 
the no longer required procvardef.

> Again: I am not saying that "the non-existent unified C-block/closure 
> reference parser" would be especially difficult to implement, I have 
> merely pointed out that, implementation-wise, having two separate 
> parsers makes sense since they can fully leverage the existing 
> infrastructure.
The thing is that you're using the *wrong* infrastructure. 
parse_proc_dec function is for parsing function/procedure/method 
declarations and definition heads, but you're parsing something that's 
in essence a fancy procedure/method variable which is completely 
independant of it being implemented by an interface. Thus it should be 
parsed the same way as a procedure/method variable.


More information about the fpc-devel mailing list