Rework TINT_INSTANTIATE_CLASS_ID() to avoid complex static initializers

The chromium tests for static initializers get upset about the call to
ClassId::New() in a global variable initializer.

Instead, take the address of a unique 'token' variable to generate the
unique identifier.

This is similar to how things were before
https://dawn-review.googlesource.com/c/tint/+/42460
but of taking the address-of the token in the header, we're instead
taking the address-of inside the cpp file, avoiding the DLL issues
that 42460 addressed.

Change-Id: Id18c5b90b365b0960fac347729a4927528d34c07
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/42462
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2021-02-25 13:41:30 +00:00 committed by Commit Bot service account
parent f8fa6cf43c
commit 2432e3429d
1 changed files with 19 additions and 13 deletions

View File

@ -25,33 +25,39 @@ namespace tint {
class ClassID; class ClassID;
/// Helper macro to instantiate the TypeInfo<T> template for `CLASS`. /// Helper macro to instantiate the TypeInfo<T> template for `CLASS`.
#define TINT_INSTANTIATE_CLASS_ID(CLASS) \ #define TINT_INSTANTIATE_CLASS_ID(CLASS) \
template <> \ template <> \
const tint::ClassID tint::TypeInfo<CLASS>::class_id { \ const char tint::UniqueToken<CLASS>::token = 0; \
tint::ClassID::New() \ template <> \
} const uintptr_t tint::TypeInfo<CLASS>::unique_id = \
reinterpret_cast<uintptr_t>(&tint::UniqueToken<CLASS>::token)
/// TypeInfo holds type information for the type T. /// TypeInfo holds type information for the type T.
/// TINT_INSTANTIATE_CLASS_ID() must be defined in a .cpp file for each type /// TINT_INSTANTIATE_CLASS_ID() must be defined in a .cpp file for each type
/// `T`. /// `T`.
template <typename T> template <typename T>
struct TypeInfo { struct TypeInfo {
static const ClassID class_id; /// The unique identifier for the type T.
static const uintptr_t unique_id;
};
/// UniqueToken holds a single static const char, which is uniquely declared for
/// each specialization of the template class.
/// Use by TINT_INSTANTIATE_CLASS_ID() to generate a unique pointer, which is in
/// turn used to generate TypeInfo<T>::unique_id.
template <typename T>
struct UniqueToken {
/// A dummy static variable that is unique for the type T.
static const char token;
}; };
/// ClassID represents a unique, comparable identifier for a C++ type. /// ClassID represents a unique, comparable identifier for a C++ type.
class ClassID { class ClassID {
public: public:
/// @returns a new and unique ClassID
static inline ClassID New() {
static uintptr_t next(0);
return ClassID(next++);
}
/// @returns the unique ClassID for the type T. /// @returns the unique ClassID for the type T.
template <typename T> template <typename T>
static inline ClassID Of() { static inline ClassID Of() {
return TypeInfo<T>::class_id; return ClassID(TypeInfo<T>::unique_id);
} }
/// Equality operator /// Equality operator