[cxx-abi-dev] Mangling C++0x Lambdas

David Vandevoorde daveed at edg.com
Mon Mar 9 15:49:07 UTC 2009


I didn't see any reactions to the ideas below, but I'd still like to  
hear "yays" or "nays" on this topic.

Furthermore, during the WG21 meeting last week, another wrinkle came  
up (see below)...

On Feb 19, 2009, at 11:37 AM, David Vandevoorde wrote:

> Hello,
>
> I'd like to continue some discussion on the topic of mangling lambda  
> closure types.
>
> In the thread of December, I suggested:
>
> On Dec 17, 2008, at 11:00 AM, David Vandevoorde wrote:
>
>>
>> On Dec 17, 2008, at 10:39 AM, John Freeman wrote:
>>
>>> Doug Gregor wrote:
>>>>
>>>> We need something that encodes the context of the lambda (function
>>>> "::foo" with no parameters) followed by, perhaps, a numbering  
>>>> scheme
>>>> within that context. The context encoding needs to account for (at
>>>> least) inline functions, classes, and namespaces.
>>>>
>>>
>>> This sounds like a problem that must have been encountered  
>>> before.  Is there already a solution for it?  At least for the  
>>> unnumbered portion?
>>
>>
>> Yes, see 5.1.6.  We can reuse that general scheme for local  
>> lambdas.  E.g.:
>>
>> 	<local-lambda-name> := Z <function encoding> E l [<discriminator>]
>>
>> and maybe introduce something similar for local unnamed classes:
>>
>> 	<local-unnamed-class_name> := Z <function encoding> E u  
>> [<discriminator>]
>>
>>
>> A tougher problem are namespace-scope lambdas (e.g., in  
>> initializers or default arguments).  There a discriminator count  
>> cannot be scope based (since the mangling then could depend on  
>> which header files were previously included, etc.).
>
>
> Later in that thread, I also suggested that nonlocal uses of lambdas  
> don't need to be matched across translation units, because they'd  
> have different types in two translation units.  For example:
>
> 	// File x.h:
> 	decltype([]{}) *p;  // ODR violation-bait
>
> 	// File y.c:
> 	#include "x.h"
>
> 	// File z.c:
> 	#include "x.h"
>
> The occurrence of the lambda in y.c and z.c produces two distinct  
> types, and so both translation units cannot be part of the same  
> program.



While the reasoning above is probably fine for non-template entities,  
it is not for templates.  For example:

	template<typename T> struct X { static int i; };
	template<typename T> int X<T>::i = []()->int { return 3; }();

This clearly should work and I think the lambda's encoding should be  
independent of the translation unit that instantiates the lambda.

Another "ODR-proof" example is

	template<typename T>
	void buzz(std::function<void(T)> fn = std::function<void(T)>([](T){}));

which probably also must work.

I see no alternative to encoding these based on the "top-level" entity  
(static data member instance in the first case, function instance in  
the second case).  Does anyone have a better idea?


>
> That said, an encoding is probably needed for lambdas that appear in  
> a class definition.  E.g.:
>
> 	struct S {
> 	  typedef decltype([]()) LT;
> 	  void f(LT);
> 	};
>
> which means that the minimal encoding above should be extended to  
> cover lambdas in nonlocal class definitions.
>
>
> We're also wondering if it would be worthwhile to add some  
> additional information to the minimal encoding so that the demangled  
> version can be more useful to programmers.
>
> For example, with a minimal encoding as proposed, the demangled  
> output might look like:
> 	lambda#1 in f(int)
> which doesn't say much about the lambda's salient properties.
>
> Would it be worthwhile to also encode the "signature" of the  
> operator() so that we could instead demangle it as
> 	lambda(int)->void in f(int) (#1)
> ?


I'm still interested in hearing comments on those issues...

	Daveed




More information about the cxx-abi-dev mailing list