When one module references another module, the build won't work

I have two Swift modules/pods: FirstPod and SecondPod. Both use C++ interop, and both call Swift classes/functions from C++.

FirstPod has this class:

open class First { … }

SecondPod has this class:

import FirstPod
public class Second: First { … }

Because Second inherits from First, the SecondPod-Swift.h header file produces build errors since it cannot find Second's base class (First) as that is nowhere included:

- Unknown class name 'First'

Code:

class SWIFT_SYMBOL("s:13Second06FirstC") Second : public FirstPod::First {
public:
  using First::First;
  using First::operator=;
  static SWIFT_INLINE_THUNK Second init() SWIFT_SYMBOL("s:13Second06FirstCACycfc");
protected:
  SWIFT_INLINE_THUNK Second(void * _Nonnull ptr) noexcept : First(ptr) {}
private:
  friend class _impl::_impl_Second;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc++17-extensions"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreserved-identifier"
  typedef char $s13Second06FirstCD;
  static inline constexpr $s13Second06FirstCD __swift_mangled_name = 0;
#pragma clang diagnostic pop
#pragma clang diagnostic pop
};
  • Forward-declaring doesn't help either, since it needs a concrete type for a base class.
  • Including FirstPod-Swift.h before I include SecondPod-Swift.h doesn't work either because (as far as I know) you cannot include the -Swift.h header of another module inside your module.

I'm out of ideas at this point. Any suggestions?

While I think the compiler probably should handle this for you, can't you forward declare First? You might might have to copy the declaration from the FirstPod-Swift.h to get the mangling right, but it should be legal. The only reason you can't do this for C++ standard library types is because it's explicitly called out as UB. It's valid to forward declare any non-std declaration.

C++20 modules change this a little, but as long as the declaration is extern "C++" it should still be fine. And I think Swift is still using old-school Clang modules anyway.