Commit 6c76acfc authored by Eric Niebler's avatar Eric Niebler Committed by Facebook Github Bot 8

folly: fix clang's -Wundefined-var-template

Summary:
[temp] (14)/6:

> A function template, member function of a class template, variable template, or static data member of a class template shall be defined in every translation unit in which it is implicitly instantiated (14.7.1) unless the corresponding specialization is explicitly instantiated (14.7.2) in some translation unit; no diagnostic is required.

`-Wundefined-var-template` warns on any implicit instantiations that are needed but could not be performed because the definition is not available. In particular, for valid code, this warns on templates/temploids which have their definition and all relevant explicit instantiations tucked away in some source file (but for which no explicit instantiation declarations are provided in the relevant header file) - used a few times in folly. This seems a bad style, the static data member template should either be defined in the header file or should be explicitly instantiated in each .cpp file.

Reviewed By: igorsugak

Differential Revision: D3447679

fbshipit-source-id: 22c90c19e2c7a9b6d772058f2c7e350b890b6c0a
parent 7815372b
......@@ -51,12 +51,31 @@
namespace folly {
namespace detail {
template <int BITS>
struct FingerprintTable {
static const uint64_t poly[1 + (BITS-1)/64];
static const uint64_t table[8][256][1 + (BITS-1)/64];
static const uint64_t poly[1 + (BITS - 1) / 64];
static const uint64_t table[8][256][1 + (BITS - 1) / 64];
};
} // namespace detail
template <int BITS>
const uint64_t FingerprintTable<BITS>::poly[1 + (BITS - 1) / 64] = {};
template <int BITS>
const uint64_t FingerprintTable<BITS>::table[8][256][1 + (BITS - 1) / 64] = {};
#define FOLLY_DECLARE_FINGERPRINT_TABLES(BITS) \
template <> \
const uint64_t FingerprintTable<BITS>::poly[1 + (BITS - 1) / 64]; \
template <> \
const uint64_t FingerprintTable<BITS>::table[8][256][1 + (BITS - 1) / 64]
FOLLY_DECLARE_FINGERPRINT_TABLES(64);
FOLLY_DECLARE_FINGERPRINT_TABLES(96);
FOLLY_DECLARE_FINGERPRINT_TABLES(128);
#undef FOLLY_DECLARE_FINGERPRINT_TABLES
} // namespace detail
/**
* Compute the Rabin fingerprint.
......
......@@ -14,9 +14,10 @@
* limitations under the License.
*/
#include "SharedMutex.h"
#include <folly/SharedMutex.h>
COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
folly::SharedMutexReadPriority);
COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
folly::SharedMutexWritePriority);
namespace folly {
// Explicitly instantiate SharedMutex here:
template class SharedMutexImpl<true>;
template class SharedMutexImpl<false>;
}
......@@ -1429,16 +1429,33 @@ class SharedMutexImpl {
}
};
#define COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(type) \
template <> \
type::DeferredReaderSlot \
type::deferredReaders[type::kMaxDeferredReaders * \
type::kDeferredSeparationFactor] = {}; \
template <> \
FOLLY_TLS uint32_t type::tls_lastTokenlessSlot = 0;
template <
bool ReaderPriority,
typename Tag_,
template <typename> class Atom,
bool BlockImmediately>
typename SharedMutexImpl<ReaderPriority, Tag_, Atom, BlockImmediately>::
DeferredReaderSlot
SharedMutexImpl<ReaderPriority, Tag_, Atom, BlockImmediately>::
deferredReaders[kMaxDeferredReaders * kDeferredSeparationFactor] =
{};
template <
bool ReaderPriority,
typename Tag_,
template <typename> class Atom,
bool BlockImmediately>
FOLLY_TLS uint32_t
SharedMutexImpl<ReaderPriority, Tag_, Atom, BlockImmediately>::
tls_lastTokenlessSlot = 0;
typedef SharedMutexImpl<true> SharedMutexReadPriority;
typedef SharedMutexImpl<false> SharedMutexWritePriority;
typedef SharedMutexWritePriority SharedMutex;
// Prevent the compiler from instantiating these in other translation units.
// They are instantiated once in SharedMutex.cpp
extern template class SharedMutexImpl<true>;
extern template class SharedMutexImpl<false>;
} // namespace folly
......@@ -28,8 +28,6 @@
#include <folly/Format.h>
#include <folly/ScopeGuard.h>
DECLARE_ACCESS_SPREADER_TYPE(std::atomic)
namespace folly {
namespace detail {
......@@ -233,21 +231,11 @@ Getcpu::Func Getcpu::resolveVdsoFunc() {
#ifdef FOLLY_TLS
/////////////// SequentialThreadId
template <>
std::atomic<size_t> SequentialThreadId<std::atomic>::prevId(0);
template <>
FOLLY_TLS size_t SequentialThreadId<std::atomic>::currentId(0);
template struct SequentialThreadId<std::atomic>;
#endif
/////////////// AccessSpreader
template <>
Getcpu::Func AccessSpreader<std::atomic>::pickGetcpuFunc() {
auto best = Getcpu::resolveVdsoFunc();
return best ? best : &FallbackGetcpuType::getcpu;
}
template struct AccessSpreader<std::atomic>;
} // namespace detail
} // namespace folly
......@@ -161,6 +161,16 @@ struct SequentialThreadId {
static FOLLY_TLS size_t currentId;
};
template <template <typename> class Atom>
Atom<size_t> SequentialThreadId<Atom>::prevId(0);
template <template <typename> class Atom>
FOLLY_TLS size_t SequentialThreadId<Atom>::currentId(0);
// Suppress this instantiation in other translation units. It is
// instantiated in CacheLocality.cpp
extern template struct SequentialThreadId<std::atomic>;
#endif
struct HashingThreadId {
......@@ -277,7 +287,10 @@ struct AccessSpreader {
static bool initialized;
/// Returns the best getcpu implementation for Atom
static Getcpu::Func pickGetcpuFunc();
static Getcpu::Func pickGetcpuFunc() {
auto best = Getcpu::resolveVdsoFunc();
return best ? best : &FallbackGetcpuType::getcpu;
}
/// Always claims to be on CPU zero, node zero
static int degenerateGetcpu(unsigned* cpu, unsigned* node, void*) {
......@@ -326,22 +339,20 @@ struct AccessSpreader {
}
};
template <>
Getcpu::Func AccessSpreader<std::atomic>::pickGetcpuFunc();
#define DECLARE_ACCESS_SPREADER_TYPE(Atom) \
namespace folly { \
namespace detail { \
template <> \
Getcpu::Func AccessSpreader<Atom>::getcpuFunc = \
AccessSpreader<Atom>::degenerateGetcpu; \
template <> \
typename AccessSpreader<Atom>::CompactStripe \
AccessSpreader<Atom>::widthAndCpuToStripe[129][128] = {}; \
template <> \
bool AccessSpreader<Atom>::initialized = AccessSpreader<Atom>::initialize(); \
} \
}
template <template <typename> class Atom>
Getcpu::Func AccessSpreader<Atom>::getcpuFunc =
AccessSpreader<Atom>::degenerateGetcpu;
template <template <typename> class Atom>
typename AccessSpreader<Atom>::CompactStripe
AccessSpreader<Atom>::widthAndCpuToStripe[kMaxCpus + 1][kMaxCpus] = {};
template <template <typename> class Atom>
bool AccessSpreader<Atom>::initialized = AccessSpreader<Atom>::initialize();
// Suppress this instantiation in other translation units. It is
// instantiated in CacheLocality.cpp
extern template struct AccessSpreader<std::atomic>;
} // namespace detail
} // namespace folly
......@@ -31,7 +31,6 @@ using namespace folly::detail;
template <typename dummy> \
struct tag {}; \
} \
DECLARE_ACCESS_SPREADER_TYPE(tag) \
namespace folly { \
namespace detail { \
template <> \
......
......@@ -413,7 +413,6 @@ TEST(AccessSpreader, Simple) {
template <typename dummy> \
struct tag {}; \
} \
DECLARE_ACCESS_SPREADER_TYPE(tag) \
namespace folly { \
namespace detail { \
template <> \
......
......@@ -15,15 +15,17 @@
*/
#include <folly/test/DeterministicSchedule.h>
#include <assert.h>
#include <algorithm>
#include <list>
#include <mutex>
#include <random>
#include <utility>
#include <unordered_map>
#include <assert.h>
#include <utility>
DECLARE_ACCESS_SPREADER_TYPE(folly::test::DeterministicAtomic)
#include <folly/Random.h>
namespace folly {
namespace test {
......@@ -139,7 +141,7 @@ int DeterministicSchedule::getRandNumber(int n) {
if (tls_sched) {
return tls_sched->scheduler_(n);
}
return std::rand() % n;
return Random::rand32() % n;
}
int DeterministicSchedule::getcpu(unsigned* cpu,
......
......@@ -42,11 +42,6 @@ typedef SharedMutexImpl<true, void, DeterministicAtomic, true>
typedef SharedMutexImpl<false, void, DeterministicAtomic, true>
DSharedMutexWritePriority;
COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
DSharedMutexReadPriority);
COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
DSharedMutexWritePriority);
template <typename Lock>
void runBasicTest() {
Lock lock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment