• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <type_traits>
6 
7 namespace not_blink {
8 
function(int x)9 void function(int x) {}
10 
11 class Class {
12  public:
method()13   void method() {}
virtualMethod()14   virtual void virtualMethod() {}
15   template <typename T>
methodTemplate(T)16   void methodTemplate(T) {}
17   template <typename T>
staticMethodTemplate(T)18   static void staticMethodTemplate(T) {}
19 };
20 
21 template <typename T>
functionTemplate(T x)22 void functionTemplate(T x) {}
23 
24 template <typename T = Class>
functionTemplate2()25 void functionTemplate2() {
26   T::staticMethodTemplate(123);
27 }
28 
29 template <typename T = Class>
30 class TemplatedClass {
31  public:
anotherMethod()32   void anotherMethod() { T::staticMethodTemplate(123); }
33 };
34 
35 }  // not_blink
36 
37 namespace blink {
38 
functionNotMarkedConstexpr(int a)39 bool functionNotMarkedConstexpr(int a) {
40   return a == 4 || a == 10;
41 }
42 
43 template <typename T>
templatedFunctionNotMarkedConstexpr(T t)44 bool templatedFunctionNotMarkedConstexpr(T t) {
45   return !!t;
46 }
47 
48 int g_globalNumber;
49 
50 template <typename T, int number>
F()51 void F() {
52   // These are const but hacker_case so we leave them alone.
53   const int maybe_a_const = sizeof(T);
54   const int is_a_const = number;
55   // These are const expressions so they get a k prefix.
56   const int maybeAConstToo = sizeof(T);
57   const int isAConstToo = number;
58   // These are built from calls to functions which produces inconsistent
59   // results so they should not be considered const to be safe.
60   const bool fromAMethod = functionNotMarkedConstexpr(number);
61   const bool fromATemplatedMethod = templatedFunctionNotMarkedConstexpr(number);
62   // A complex statement of const things is const.
63   const bool complexConst = number || (number + 1);
64   // A complex statement with a non-const thing is not const.
65   const bool complexNotConst = number || (g_globalNumber + 1);
66   // A const built from other consts is a const.
67   const bool constFromAConst = complexConst || number;
68 }
69 
70 template <int number, typename... T>
F()71 void F() {
72   // These are const but hacker_case so we leave them alone.
73   const int maybe_a_const = sizeof...(T);
74   const int is_a_const = number;
75   // These are const expressions so they get a k prefix.
76   const int maybeAConstToo = sizeof...(T);
77   const int isAConstToo = number;
78 }
79 
80 namespace test_member_in_template {
81 
82 template <typename T>
83 class HasAMember {
84  public:
HasAMember()85   HasAMember() {}
HasAMember(const T &)86   HasAMember(const T&) {}
87 
usesMember()88   void usesMember() { const int notConst = m_i; }
89   void alsoUsesMember();
90 
91  private:
92   int m_i;
93 };
94 
95 template <typename T>
alsoUsesMember()96 void HasAMember<T>::alsoUsesMember() {
97   const int notConst = m_i;
98 }
99 
100 template <typename T>
basedOnSubType(const HasAMember<T> & t)101 static void basedOnSubType(const HasAMember<T>& t) {
102   const HasAMember<T> problematicNotConst(t);
103 }
104 
Run()105 void Run() {
106   HasAMember<int>().usesMember();
107 
108   basedOnSubType<int>(HasAMember<int>());
109   enum E { A };
110   basedOnSubType<E>(HasAMember<E>());
111 }
112 }
113 
114 namespace test_template_arg_is_function {
115 
f(int x)116 void f(int x) {}
117 
118 template <typename T, void g(T)>
h(T x)119 void h(T x) {
120   g(x);
121 }
122 
test()123 void test() {
124   // f should be rewritten.
125   h<int, f>(0);
126   // Non-Blink should stay the same.
127   h<int, not_blink::function>(1);
128 
129   // The int one makes the methods called from F() considered as constexpr, and
130   // can be collapsed to not have template arguments before it reaches the AST.
131   F<int, 10>();
132   // The enum one makes them not constexpr, as it doesn't collapse away the
133   // template stuff as much. This can lead to conflicting decisions about
134   // the names inside F() vs the above instantiation.
135   enum E { A };
136   F<E, 11>();
137 }
138 
139 }  // namespace test_template_arg_is_function
140 
141 namespace test_template_arg_is_method {
142 
143 class Class {
144  public:
method()145   void method() {}
146 };
147 
148 template <typename T, void (T::*g)()>
h(T && x)149 void h(T&& x) {
150   (x.*g)();
151 }
152 
test()153 void test() {
154   // method should be rewritten.
155   h<Class, &Class::method>(Class());
156   // Non-Blink should stay the same.
157   h<not_blink::Class, &not_blink::Class::method>(not_blink::Class());
158 }
159 
160 }  // namespace test_template_arg_is_method
161 
162 namespace test_template_arg_is_function_template {
163 
164 namespace nested {
165 template <typename T>
f(T)166 void f(T) {}
167 }
168 
169 template <typename T, void g(T)>
h(T x)170 void h(T x) {
171   g(x);
172 }
173 
test()174 void test() {
175   // f should be rewritten.
176   h<int, nested::f>(0);
177   // Non-Blink should stay the same.
178   h<int, not_blink::functionTemplate>(1);
179 }
180 
181 }  // namespace test_template_arg_is_function_template
182 
183 namespace test_template_arg_is_method_template_in_non_member_context {
184 
185 struct Class {
186   template <typename T>
fblink::test_template_arg_is_method_template_in_non_member_context::Class187   static void f(T) {}
188 };
189 
190 template <typename T, void g(T)>
h(T x)191 void h(T x) {
192   g(x);
193 }
194 
test()195 void test() {
196   // f should be rewritten.
197   h<int, Class::f>(0);
198   // Non-Blink should stay the same.
199   h<int, not_blink::Class::staticMethodTemplate>(1);
200 }
201 
202 }  // test_template_arg_is_method_template_in_non_member_context
203 
204 namespace test_inherited_field {
205 
206 template <typename T>
207 class BaseClass {
208  public:
209   unsigned long m_size;
210 };
211 
212 template <typename T>
213 class DerivedClass : protected BaseClass<T> {
214  private:
215   using Base = BaseClass<T>;
216   // https://crbug.com/640016: Need to rewrite |m_size| into |size_|.
217   using Base::m_size;
method()218   void method() { m_size = 123; }
219 };
220 
221 }  // namespace test_inherited_field
222 
223 namespace test_template_arg_is_method_template_in_member_context {
224 
225 struct Class {
226   template <typename T>
fblink::test_template_arg_is_method_template_in_member_context::Class227   static void f(T) {}
228 };
229 
230 struct Class2 {
231   template <typename T>
fblink::test_template_arg_is_method_template_in_member_context::Class2232   void f(T x) {
233     // f should be rewritten.
234     Class c;
235     c.f(x);
236     // Non-Blink should stay the same.
237     not_blink::Class c2;
238     c2.method(x);
239   }
240 };
241 
242 }  // namespace test_template_arg_is_method_template_in_member_context
243 
244 namespace test_unnamed_arg {
245 
246 template <typename T>
247 class Class {
248  public:
249   // Test for https://crbug.com/598141 - shouldn't rewrite
250   //    ...int);
251   // into
252   //    ...intdata_size;
253   void f(int);
254 };
255 
256 template <typename T>
f(int dataSize)257 void Class<T>::f(int dataSize){};
258 
foo()259 void foo() {
260   Class<char>().f(123);
261 };
262 
263 }  // namespace test_unnamed_arg
264 
265 namespace cxx_dependent_scope_member_expr_testing {
266 
267 class PartitionAllocator {
268  public:
method()269   static void method() {}
270 };
271 
272 template <typename Allocator = PartitionAllocator>
273 class Vector {
274  public:
275   // https://crbug.com/582315: |Allocator::method| is a
276   // CXXDependentScopeMemberExpr.
anotherMethod()277   void anotherMethod() {
278     if (std::is_class<Allocator>::value)  // Shouldn't rename |value|
279       Allocator::method();                // Should rename |method| -> |Method|.
280   }
281 };
282 
283 template <typename Allocator = PartitionAllocator>
test()284 void test() {
285   // https://crbug.com/582315: |Allocator::method| is a
286   // DependentScopeDeclRefExpr.
287   if (std::is_class<Allocator>::value)  // Shouldn't rename |value|.
288     Allocator::method();                // Should rename |method|.
289 }
290 
291 class InterceptingCanvasBase : public ::not_blink::Class {
292  public:
virtualMethodInBlink()293   virtual void virtualMethodInBlink(){};
294 };
295 
296 template <typename DerivedCanvas>
297 class InterceptingCanvas : public InterceptingCanvasBase {
298  public:
virtualMethod()299   void virtualMethod() override {
300     this->Class::virtualMethod();  // https://crbug.com/582315#c19
301     this->InterceptingCanvasBase::virtualMethodInBlink();
302   }
303 };
304 
305 template <typename T>
306 class ThreadSpecific {
307  public:
308   T* operator->();
309   operator T*();
310 };
311 
312 template <typename T>
operator T*()313 inline ThreadSpecific<T>::operator T*() {
314   return nullptr;
315 }
316 
317 template <typename T>
operator ->()318 inline T* ThreadSpecific<T>::operator->() {
319   return operator T*();
320 }
321 
322 class Class {
323  public:
virtualMethodInBlink()324   virtual void virtualMethodInBlink() {}
325 };
326 
327 }  // namespace cxx_dependent_scope_member_expr_testing
328 
329 namespace blacklisting_of_renaming_of_begin_method {
330 
331 template <typename T>
332 class IntrusiveHeap {
333  public:
334   // https://crbug.com/672353: |begin| shouldn't be rewritten to |Begin|.
begin() const335   const T* begin() const { return nullptr; }
336 };
337 
338 }  // namespace blacklisting_of_renaming_of_begin_method
339 
340 }  // namespace blink
341 
342 namespace not_blink {
343 
344 namespace cxx_dependent_scope_member_expr_testing {
345 
346 class Base : public ::blink::cxx_dependent_scope_member_expr_testing::Class {
347  public:
virtualMethod()348   virtual void virtualMethod() {}
349 };
350 
351 template <typename T>
352 class Derived : public Base {
353  public:
virtualMethod()354   void virtualMethod() override {
355     this->Class::virtualMethodInBlink();
356     this->Base::virtualMethod();
357   }
358 };
359 
360 }  // namespace cxx_dependent_scope_member_expr_testing
361 
362 namespace blink_methods_called_from_mojo_traits_are_not_rewritten {
363 
364 template <typename V>
365 struct MapTraits;
366 
367 template <typename V>
368 struct MapTraits<blink::test_unnamed_arg::Class<V>> {
SetToEmptynot_blink::blink_methods_called_from_mojo_traits_are_not_rewritten::MapTraits369   static void SetToEmpty(blink::test_unnamed_arg::Class<V>* output) {
370     // Need to rewrite |f| to |F| below (because this method name
371     // does get rewritten when processing blink::test_unnamed_arg::Class).
372     // See also https://crbug.com/670434.
373     output->f(123);
374   }
375 };
376 
377 }  // namespace blink_methods_called_from_mojo_traits_are_not_rewritten
378 
379 }  // namespace not_blink
380