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>
diff --git a/src/castable.h b/src/castable.h
index 9528d96..1fe4464 100644
--- a/src/castable.h
+++ b/src/castable.h
@@ -25,33 +25,39 @@
 class ClassID;
 
 /// Helper macro to instantiate the TypeInfo<T> template for `CLASS`.
-#define TINT_INSTANTIATE_CLASS_ID(CLASS)                \
-  template <>                                           \
-  const tint::ClassID tint::TypeInfo<CLASS>::class_id { \
-    tint::ClassID::New()                                \
-  }
+#define TINT_INSTANTIATE_CLASS_ID(CLASS)             \
+  template <>                                        \
+  const char tint::UniqueToken<CLASS>::token = 0;    \
+  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.
 /// TINT_INSTANTIATE_CLASS_ID() must be defined in a .cpp file for each type
 /// `T`.
 template <typename T>
 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.
 class ClassID {
  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.
   template <typename T>
   static inline ClassID Of() {
-    return TypeInfo<T>::class_id;
+    return ClassID(TypeInfo<T>::unique_id);
   }
 
   /// Equality operator