PSA: -f[no-]objc-encode-cxx-class-template-spec

David Chisnall <[email protected]> Fri, 28 May 2021 08:55:39 +0100
Newsgroups gmane.comp.lib.gnustep.devel
Message-ID <[email protected]>
Hello everyone,

Clang now provides an option -fobjc-encode-cxx-class-template-spec / 
-fno-objc-encode-cxx-class-template-spec to specify whether encodings 
that include C++ types with template parameters should be mangled in 
full or abbreviated to ^v.  This is an ABI-breaking flag for the GNUstep 
ABI, where type encodings are used both in dispatch lookup and in ivar 
offset variables.  If you have an Objective-C++ codebase that uses a lot 
of template instantiations, this will give you smaller binaries.  It is 
safe to use *only* if you do not expose ivars or methods in your public 
headers that include templated C++ types.

For example, this is safe:

public_header.h
```obj-c
@interface UnorderedStringMap
- (id)objectForKey: (NSString*)aKey;
@end
```


private.m:
```obj-c
@implementation UnorderedStringMap
{
	@private
	std::unordered_map<NSString*, id> map;
}
- (id)objectForKey: (NSString*)aKey
{
	return map[aKey];
}
@end
```

This is not:

public_header.h

```obj-c
@interface UnorderedStringMap
{
	@public:
	// ivar can't be found if the flag differs between two compilation units
	std::unordered_map<NSString*, id> map;
}
- (id)objectForKey: (NSString*)aKey;
// Method can't be called if the flag differs between two compilation units.
- (void)resetMap: (std::unordered_map<NSString*, id>&&)aMap;
@end
```

If you use Objective-C++ internally but expose only Objective-C 
interfaces, then you may find this flag useful.


David