Skip to content

Commit

Permalink
Move extern template instantiates to the end of file (#17849)
Browse files Browse the repository at this point in the history
There is a difference in behavior between gcc and clang when it comes to
explicit instantiating extern templates. With clang, instantiating
before all templated member definitions are defined will leave those
members uninstantiated in the translation unit, causing undefined symbol
errors.

Move the instantiation to the end of file so these platforms can build
with clang.
  • Loading branch information
mspang authored and pull[bot] committed Feb 8, 2024
1 parent 18a1a0e commit f093ef0
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ namespace chip {
namespace DeviceLayer {
namespace Internal {

// Fully instantiate the template class in whatever compilation unit includes this file.
template class GenericConnectivityManagerImpl_BLE<ConnectivityManagerImpl>;

template <class ImplClass>
const char * GenericConnectivityManagerImpl_BLE<ImplClass>::_CHIPoBLEServiceModeToStr(ConnectivityManager::CHIPoBLEServiceMode mode)
{
Expand All @@ -50,6 +47,10 @@ const char * GenericConnectivityManagerImpl_BLE<ImplClass>::_CHIPoBLEServiceMode
}
}

// Fully instantiate the template class in whatever compilation unit includes this file.
// NB: This must come after all templated class members are defined.
template class GenericConnectivityManagerImpl_BLE<ConnectivityManagerImpl>;

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ namespace chip {
namespace DeviceLayer {
namespace Internal {

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericConnectivityManagerImpl_WiFi<ConnectivityManagerImpl>;

template <class ImplClass>
const char * GenericConnectivityManagerImpl_WiFi<ImplClass>::_WiFiStationModeToStr(ConnectivityManager::WiFiStationMode mode)
{
Expand Down Expand Up @@ -121,6 +118,10 @@ bool GenericConnectivityManagerImpl_WiFi<ImplClass>::_IsWiFiStationEnabled()
return Impl()->GetWiFiStationMode() == ConnectivityManager::kWiFiStationMode_Enabled;
}

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
// NB: This must come after all templated class members are defined.
template class GenericConnectivityManagerImpl_WiFi<ConnectivityManagerImpl>;

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ void GenericPlatformManagerImpl<ImplClass>::HandleMessageLayerActivityChanged(bo
}

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
// NB: This must come after all templated class members are defined.
template class GenericPlatformManagerImpl<PlatformManagerImpl>;

} // namespace Internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ namespace chip {
namespace DeviceLayer {
namespace Internal {

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>;

template <class ImplClass>
CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_InitChipStack(void)
{
Expand Down Expand Up @@ -288,6 +285,10 @@ CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS<ImplClass>::_StopEventLoopTask(vo
return CHIP_NO_ERROR;
}

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
// NB: This must come after all templated class members are defined.
template class GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>;

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ CHIP_ERROR GenericPlatformManagerImpl_POSIX<ImplClass>::_Shutdown()
}

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
// NB: This must come after all templated class members are defined.
template class GenericPlatformManagerImpl_POSIX<PlatformManagerImpl>;

} // namespace Internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ System::LayerSocketsLoop & SystemLayerSocketsLoop()

} // anonymous namespace

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericPlatformManagerImpl_Zephyr<PlatformManagerImpl>;

template <class ImplClass>
CHIP_ERROR GenericPlatformManagerImpl_Zephyr<ImplClass>::_InitChipStack(void)
{
Expand Down Expand Up @@ -197,6 +194,10 @@ CHIP_ERROR GenericPlatformManagerImpl_Zephyr<ImplClass>::_StartEventLoopTask(voi
return CHIP_NO_ERROR;
}

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
// NB: This must come after all templated class members are defined.
template class GenericPlatformManagerImpl_Zephyr<PlatformManagerImpl>;

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ namespace chip {
namespace DeviceLayer {
namespace Internal {

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericThreadStackManagerImpl_FreeRTOS<ThreadStackManagerImpl>;

template <class ImplClass>
CHIP_ERROR GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::DoInit(void)
{
Expand Down Expand Up @@ -144,6 +141,10 @@ void GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::ThreadTaskMain(void * ar
}
}

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
// NB: This must come after all templated class members are defined.
template class GenericThreadStackManagerImpl_FreeRTOS<ThreadStackManagerImpl>;

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ void initNetworkCommissioningThreadDriver(void)
NetworkCommissioning::ThreadScanResponse * sScanResult;
otScanResponseIterator<NetworkCommissioning::ThreadScanResponse> mScanResponseIter(sScanResult);
} // namespace
// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericThreadStackManagerImpl_OpenThread<ThreadStackManagerImpl>;

/**
* Called by OpenThread to alert the ThreadStackManager of a change in the state of the Thread stack.
Expand Down Expand Up @@ -2584,6 +2582,10 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_DnsResolve(cons
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
// NB: This must come after all templated class members are defined.
template class GenericThreadStackManagerImpl_OpenThread<ThreadStackManagerImpl>;

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ namespace chip {
namespace DeviceLayer {
namespace Internal {

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericThreadStackManagerImpl_OpenThread_LwIP<ThreadStackManagerImpl>;

template <class ImplClass>
void GenericThreadStackManagerImpl_OpenThread_LwIP<ImplClass>::_OnPlatformEvent(const ChipDeviceEvent * event)
{
Expand Down Expand Up @@ -422,6 +419,10 @@ void GenericThreadStackManagerImpl_OpenThread_LwIP<ImplClass>::ReceivePacket(otM
}
}

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
// NB: This must come after all templated class members are defined.
template class GenericThreadStackManagerImpl_OpenThread_LwIP<ThreadStackManagerImpl>;

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip

0 comments on commit f093ef0

Please sign in to comment.