From 3978811f0fc2fb8976abd789f0364f1d6873b8d4 Mon Sep 17 00:00:00 2001 From: Michael Spang Date: Thu, 28 Apr 2022 22:05:04 -0400 Subject: [PATCH] Move extern template instantiates to the end of file (#17849) 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. --- .../internal/GenericConnectivityManagerImpl_BLE.ipp | 7 ++++--- .../internal/GenericConnectivityManagerImpl_WiFi.ipp | 7 ++++--- .../platform/internal/GenericPlatformManagerImpl.ipp | 1 + .../internal/GenericPlatformManagerImpl_FreeRTOS.ipp | 7 ++++--- .../platform/internal/GenericPlatformManagerImpl_POSIX.ipp | 1 + .../internal/GenericPlatformManagerImpl_Zephyr.ipp | 7 ++++--- .../FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.cpp | 7 ++++--- .../GenericThreadStackManagerImpl_OpenThread.cpp | 6 ++++-- .../GenericThreadStackManagerImpl_OpenThread_LwIP.cpp | 7 ++++--- 9 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/include/platform/internal/GenericConnectivityManagerImpl_BLE.ipp b/src/include/platform/internal/GenericConnectivityManagerImpl_BLE.ipp index 1dc9c5a692e797..8e616bc98ccad6 100644 --- a/src/include/platform/internal/GenericConnectivityManagerImpl_BLE.ipp +++ b/src/include/platform/internal/GenericConnectivityManagerImpl_BLE.ipp @@ -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; - template const char * GenericConnectivityManagerImpl_BLE::_CHIPoBLEServiceModeToStr(ConnectivityManager::CHIPoBLEServiceMode mode) { @@ -50,6 +47,10 @@ const char * GenericConnectivityManagerImpl_BLE::_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; + } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/include/platform/internal/GenericConnectivityManagerImpl_WiFi.ipp b/src/include/platform/internal/GenericConnectivityManagerImpl_WiFi.ipp index 411eb4d4dcf69a..4597f27a5d416b 100644 --- a/src/include/platform/internal/GenericConnectivityManagerImpl_WiFi.ipp +++ b/src/include/platform/internal/GenericConnectivityManagerImpl_WiFi.ipp @@ -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; - template const char * GenericConnectivityManagerImpl_WiFi::_WiFiStationModeToStr(ConnectivityManager::WiFiStationMode mode) { @@ -121,6 +118,10 @@ bool GenericConnectivityManagerImpl_WiFi::_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; + } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.ipp b/src/include/platform/internal/GenericPlatformManagerImpl.ipp index 9bb7dd8065e654..c3e2370748395c 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl.ipp +++ b/src/include/platform/internal/GenericPlatformManagerImpl.ipp @@ -321,6 +321,7 @@ void GenericPlatformManagerImpl::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; } // namespace Internal diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp b/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp index 216665c08560de..b69448724b9002 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp +++ b/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp @@ -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; - template CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS::_InitChipStack(void) { @@ -288,6 +285,10 @@ CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS::_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; + } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.ipp b/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.ipp index 81d7e00ee3da3c..708f44e3bdf431 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.ipp +++ b/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.ipp @@ -311,6 +311,7 @@ CHIP_ERROR GenericPlatformManagerImpl_POSIX::_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; } // namespace Internal diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.ipp b/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.ipp index 89fea684bee9ce..217edb70fed89b 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.ipp +++ b/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.ipp @@ -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; - template CHIP_ERROR GenericPlatformManagerImpl_Zephyr::_InitChipStack(void) { @@ -197,6 +194,10 @@ CHIP_ERROR GenericPlatformManagerImpl_Zephyr::_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; + } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.cpp b/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.cpp index ab8af54c569dc5..4dbee81b23af01 100644 --- a/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.cpp +++ b/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.cpp @@ -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; - template CHIP_ERROR GenericThreadStackManagerImpl_FreeRTOS::DoInit(void) { @@ -144,6 +141,10 @@ void GenericThreadStackManagerImpl_FreeRTOS::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; + } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp index 5d786ca9815ce2..3713b5ccaf6576 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp @@ -102,8 +102,6 @@ void initNetworkCommissioningThreadDriver(void) NetworkCommissioning::ThreadScanResponse * sScanResult; otScanResponseIterator mScanResponseIter(sScanResult); } // namespace -// Fully instantiate the generic implementation class in whatever compilation unit includes this file. -template class GenericThreadStackManagerImpl_OpenThread; /** * Called by OpenThread to alert the ThreadStackManager of a change in the state of the Thread stack. @@ -2584,6 +2582,10 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_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; + } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp index 4d235a925470de..a08c4acea48eab 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp @@ -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; - template void GenericThreadStackManagerImpl_OpenThread_LwIP::_OnPlatformEvent(const ChipDeviceEvent * event) { @@ -422,6 +419,10 @@ void GenericThreadStackManagerImpl_OpenThread_LwIP::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; + } // namespace Internal } // namespace DeviceLayer } // namespace chip