1f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Copyright 2015 The Chromium Authors. All rights reserved.
2f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// found in the LICENSE file.
4f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace blink {
6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Note: do not add any copy or move constructors to this class: doing so will
8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// break test coverage that we don't clobber the class name by trying to emit
9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// replacements for synthesized functions.
10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass C {
11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
12f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Make sure initializers are updated to use the new names.
13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  C() : m_flagField(~0), m_fieldMentioningHTTPAndHTTPS(1), m_shouldRename(0) {}
14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int method() {
16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Test that references to fields are updated correctly.
17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return instanceCount + m_flagField + m_fieldMentioningHTTPAndHTTPS;
18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Test that a field without a m_ prefix is correctly renamed.
21f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int instanceCount;
22f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
23f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch protected:
24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Test that a field with a m_ prefix is correctly renamed.
25f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const int m_flagField;
26f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Statics should be named with s_, but make sure s_ and m_ are both correctly
27f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // stripped.
28f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int s_staticCount;
29f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int m_staticCountWithBadName;
30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Make sure that acronyms don't confuse the underscore inserter.
31f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int m_fieldMentioningHTTPAndHTTPS;
32f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Already Google style, should not change.
33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int already_google_style_;
34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  union {
36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Anonymous union members should be renamed, as should contructor
37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // initializers of them.
38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    char* m_shouldRename;
39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int* m_doesRename;
40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  };
41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct Derived : public C {
44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  using C::m_flagField;
45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  using C::m_fieldMentioningHTTPAndHTTPS;
46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint C::instanceCount = 0;
49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Structs are like classes.
51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct S {
52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int m_integerField;
53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int wantsRename;
54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int google_style_already;
55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Unions also use struct-style naming.
58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochunion U {
59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char fourChars[4];
60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  short twoShorts[2];
61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int one_hopefully_four_byte_int;
62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int m_hasPrefix;
63f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
64f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// https://crbug.com/640749#c1: Some type traits are inside blink namespace.
66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct IsGarbageCollectedMixin {
67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static const bool value = true;
68f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
70f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace blink
71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
72f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace WTF {
73f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// We don't want to capitalize fields in type traits
75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// (i.e. the |value| -> |kValue| rename is undesirable below).
76f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct TypeTrait1 {
77f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static const bool value = true;
78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
79f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
80f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Some type traits are implemented as classes, not structs
81f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// (e.g. WTF::IsGarbageCollectedType or WTF::IsAssignable).
82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// We should not perform a |value| -> |kValue| rename in the type trait below.
83f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T>
84f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass TypeTrait2 {
85f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
86f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static const bool value = false;
87f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
88f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <>
89f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass TypeTrait2<void> {
90f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
91f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static const bool value = false;
92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
93f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
94f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Some type traits have static methods.  We should not perform
95f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// a |value| -> |kValue| rename in the type trait below.
96f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T, typename U>
97f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct IsSubclass {
98f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
99f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef char YesType;
100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  struct NoType {
101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    char padding[8];
102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  };
103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static YesType subclassCheck(U*);
105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static NoType subclassCheck(...);
106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static T* t;
107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Some type traits have deleted instance methods.  We should not perform
113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// a |value| -> |kValue| rename in the type trait below.
114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename U = void>
115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct IsTraceableInCollection {
116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Expanded from STATIC_ONLY(IsTraceableInCollection) macro:
117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IsTraceableInCollection() = delete;
119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IsTraceableInCollection(const IsTraceableInCollection&) = delete;
120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IsTraceableInCollection& operator=(const IsTraceableInCollection&) = delete;
121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void* operator new(unsigned long) = delete;
122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void* operator new(unsigned long, void*) = delete;
123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static const bool value = true;
126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Some type traits have a non-boolean value.
129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochenum LifetimeManagementType {
130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RefCountedLifetime,
131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  GarbageCollectedLifetime,
132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T>
134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct LifetimeOf {
135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Okay to rename |isGarbageCollected| to |kIsGarbageCollected|.
137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static const bool isGarbageCollected = true;
138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Expecting no rename of |value|.
141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static const LifetimeManagementType value =
142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      !isGarbageCollected ? RefCountedLifetime : GarbageCollectedLifetime;
143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
14562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <typename T>
14662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstruct GenericHashTraitsBase {
14762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // We don't want to capitalize fields in type traits
14862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // (i.e. the |value| -> |kValue| rename is undesirable below).
14962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // This problem is prevented by IsCallee heuristic.
15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static const int kWeakHandlingFlag = TypeTrait2<T>::value ? 123 : 456;
15162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch};
15262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
15362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <int Format>
15462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstruct IntermediateFormat {
15562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Some type traits have int type.  Example below is loosely based on
15662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp
15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static const int value = (Format == 123) ? 456 : 789;
15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch};
15962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};  // namespace WTF
161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid F() {
163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Test that references to a static field are correctly rewritten.
164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  blink::C::instanceCount++;
165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Force instantiation of a copy constructor for blink::C to make sure field
166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // initializers for synthesized functions don't cause weird rewrites.
167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  blink::C c;
168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  blink::C c2 = c;
169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool b1 = WTF::TypeTrait1::value;
171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool b2 = WTF::TypeTrait2<void>::value;
172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
173