// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include namespace not_blink { void function(int x) {} class Class { public: void method() {} virtual void virtualMethod() {} template void methodTemplate(T) {} template static void staticMethodTemplate(T) {} }; template void functionTemplate(T x) {} template void functionTemplate2() { T::staticMethodTemplate(123); } template class TemplatedClass { public: void anotherMethod() { T::staticMethodTemplate(123); } }; } // not_blink namespace blink { bool FunctionNotMarkedConstexpr(int a) { return a == 4 || a == 10; } template bool TemplatedFunctionNotMarkedConstexpr(T t) { return !!t; } int g_global_number; template void F() { // These are const but hacker_case so we leave them alone. const int maybe_a_const = sizeof(T); const int is_a_const = number; // These are const expressions so they get a k prefix. const int kMaybeAConstToo = sizeof(T); const int kIsAConstToo = number; // These are built from calls to functions which produces inconsistent // results so they should not be considered const to be safe. const bool from_a_method = FunctionNotMarkedConstexpr(number); const bool from_a_templated_method = TemplatedFunctionNotMarkedConstexpr(number); // A complex statement of const things is const. const bool kComplexConst = number || (number + 1); // A complex statement with a non-const thing is not const. const bool complex_not_const = number || (g_global_number + 1); // A const built from other consts is a const. const bool kConstFromAConst = kComplexConst || number; } template void F() { // These are const but hacker_case so we leave them alone. const int maybe_a_const = sizeof...(T); const int is_a_const = number; // These are const expressions so they get a k prefix. const int kMaybeAConstToo = sizeof...(T); const int kIsAConstToo = number; } namespace test_member_in_template { template class HasAMember { public: HasAMember() {} HasAMember(const T&) {} void UsesMember() { const int not_const = i_; } void AlsoUsesMember(); private: int i_; }; template void HasAMember::AlsoUsesMember() { const int not_const = i_; } template static void BasedOnSubType(const HasAMember& t) { const HasAMember problematic_not_const(t); } void Run() { HasAMember().UsesMember(); BasedOnSubType(HasAMember()); enum E { A }; BasedOnSubType(HasAMember()); } } namespace test_template_arg_is_function { void F(int x) {} template void H(T x) { g(x); } void Test() { // f should be rewritten. H(0); // Non-Blink should stay the same. H(1); // The int one makes the methods called from F() considered as constexpr, and // can be collapsed to not have template arguments before it reaches the AST. F(); // The enum one makes them not constexpr, as it doesn't collapse away the // template stuff as much. This can lead to conflicting decisions about // the names inside F() vs the above instantiation. enum E { A }; F(); } } // namespace test_template_arg_is_function namespace test_template_arg_is_method { class Class { public: void Method() {} }; template void H(T&& x) { (x.*g)(); } void Test() { // method should be rewritten. H(Class()); // Non-Blink should stay the same. H(not_blink::Class()); } } // namespace test_template_arg_is_method namespace test_template_arg_is_function_template { namespace nested { template void F(T) {} } template void H(T x) { g(x); } void Test() { // f should be rewritten. H(0); // Non-Blink should stay the same. H(1); } } // namespace test_template_arg_is_function_template namespace test_template_arg_is_method_template_in_non_member_context { struct Class { template static void F(T) {} }; template void H(T x) { g(x); } void Test() { // f should be rewritten. H(0); // Non-Blink should stay the same. H(1); } } // test_template_arg_is_method_template_in_non_member_context namespace test_inherited_field { template class BaseClass { public: unsigned long size_; }; template class DerivedClass : protected BaseClass { private: using Base = BaseClass; // https://crbug.com/640016: Need to rewrite |m_size| into |size_|. using Base::size_; void Method() { size_ = 123; } }; } // namespace test_inherited_field namespace test_template_arg_is_method_template_in_member_context { struct Class { template static void F(T) {} }; struct Class2 { template void F(T x) { // f should be rewritten. Class c; c.F(x); // Non-Blink should stay the same. not_blink::Class c2; c2.method(x); } }; } // namespace test_template_arg_is_method_template_in_member_context namespace test_unnamed_arg { template class Class { public: // Test for https://crbug.com/598141 - shouldn't rewrite // ...int); // into // ...intdata_size; void F(int); }; template void Class::F(int data_size){}; void Foo() { Class().F(123); }; } // namespace test_unnamed_arg namespace cxx_dependent_scope_member_expr_testing { class PartitionAllocator { public: static void Method() {} }; template class Vector { public: // https://crbug.com/582315: |Allocator::method| is a // CXXDependentScopeMemberExpr. void AnotherMethod() { if (std::is_class::value) // Shouldn't rename |value| Allocator::Method(); // Should rename |method| -> |Method|. } }; template void Test() { // https://crbug.com/582315: |Allocator::method| is a // DependentScopeDeclRefExpr. if (std::is_class::value) // Shouldn't rename |value|. Allocator::Method(); // Should rename |method|. } class InterceptingCanvasBase : public ::not_blink::Class { public: virtual void VirtualMethodInBlink(){}; }; template class InterceptingCanvas : public InterceptingCanvasBase { public: void virtualMethod() override { this->Class::virtualMethod(); // https://crbug.com/582315#c19 this->InterceptingCanvasBase::VirtualMethodInBlink(); } }; template class ThreadSpecific { public: T* operator->(); operator T*(); }; template inline ThreadSpecific::operator T*() { return nullptr; } template inline T* ThreadSpecific::operator->() { return operator T*(); } class Class { public: virtual void VirtualMethodInBlink() {} }; } // namespace cxx_dependent_scope_member_expr_testing namespace blacklisting_of_renaming_of_begin_method { template class IntrusiveHeap { public: // https://crbug.com/672353: |begin| shouldn't be rewritten to |Begin|. const T* begin() const { return nullptr; } }; } // namespace blacklisting_of_renaming_of_begin_method } // namespace blink namespace not_blink { namespace cxx_dependent_scope_member_expr_testing { class Base : public ::blink::cxx_dependent_scope_member_expr_testing::Class { public: virtual void virtualMethod() {} }; template class Derived : public Base { public: void virtualMethod() override { this->Class::VirtualMethodInBlink(); this->Base::virtualMethod(); } }; } // namespace cxx_dependent_scope_member_expr_testing namespace blink_methods_called_from_mojo_traits_are_not_rewritten { template struct MapTraits; template struct MapTraits> { static void SetToEmpty(blink::test_unnamed_arg::Class* output) { // Need to rewrite |f| to |F| below (because this method name // does get rewritten when processing blink::test_unnamed_arg::Class). // See also https://crbug.com/670434. output->F(123); } }; } // namespace blink_methods_called_from_mojo_traits_are_not_rewritten } // namespace not_blink