Is it possible to add `swift_attr` to a class forward declaration outside of a 3rd party library?


I'm playing with swift's c++ interoperability using GitHub - plotfi/SwiftBox2D: box2d Hello World ported to Swift using C++-Interop as an example, it works but it is not perfect in my point of view: the solution needs to modify the 3rd party source code, see SwiftBox2D/box2d-modifications/b2_body.h.patch at main · plotfi/SwiftBox2D (

It modifies the b2_body.h file from

class B2_API b2Body


class B2_API IMMORTAL_REF b2Body

where IMMORTAL_REF is swift_attr is:

#define IMMORTAL_REF                                \
      __attribute__((swift_attr("import_as_ref")))   \
      __attribute__((swift_attr("retain:immortal"))) \

So basically, the solution needs to modify the source code and add swift_attr. I know this is a currently known issue for swift importing c++ libraries, but is it possible to have a better solution?

Currently I'm thinking of forward declaration in c++. Before we include any 3rd party code, we can forward declare the class like this:

class IMMORTAL_REF b2Body;

This is not a definition but a forward declaration, it can be added outside the 3rd party library before including its header files. It's a good place to tell the swift compiler about the swift_attr. If it's possible then it will be a perfect solution and the 3rd party source code is untouched.

But it's not possible. After I add IMMORTAL_REF in the forward declaration but not in the class definition, I got this error:

box2d\b2_body.h:128:14: error: reference type 'b2Body' must have 'retain:' swift attribute
class B2_API b2Body

I guess it's because of the inconsistency of IMMORTAL_REF usage.

I also read that __attribute__ is compiler specific and never standardized (maybe I'm wrong), therefore can we make it possible to add swift_attr in forward declaration? It will be a compiler change I'm afraid.

I was trying to do the same thing as well when creating a C++/Swift mixed library.
In the process of replacing objc++ sources with Swift equivalents, I noticed that the lifetime of externally defined types (in my case ImGui types) had gotten value type semantics, which breaks its behaviour. So I thought that adding these attributes in the bridging header could solve it.
However, it is impossible to get them to have reference type semantics without having the modify the shared (it's used by other parts of the project as well) 3rd party library.

Interestingly enough, it gives a specific warning when misplacing the SWIFT_SHARED_REFERENCE macro in context of type declaration:

So to some extent, the compiler is aware about adding attributes to type declarations.