| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <cstdint> |
| #include <string> |
| #include <vector> |
| |
| namespace my_namespace { |
| |
| class SomeClass { |
| public: |
| void Method(char) {} |
| int data_member; |
| }; |
| |
| template <typename T> |
| struct SomeTemplate { |
| T t; |
| }; |
| |
| struct MyStruct { |
| // Expected rewrite: raw_ptr<raw_ptr<SomeClass>> double_ptr; |
| // TODO(lukasza): Handle recursion/nesting. |
| SomeClass** double_ptr; |
| |
| // Expected rewrite: raw_ptr<void> void_ptr; |
| void* void_ptr; |
| |
| // |bool*| used to be rewritten as |raw_ptr<_Bool>| which doesn't compile: |
| // use of undeclared identifier '_Bool'. |
| // |
| // Expected rewrite: raw_ptr<bool> bool_ptr; |
| bool* bool_ptr; |
| // Expected rewrite: raw_ptr<const bool> bool_ptr; |
| const bool* const_bool_ptr; |
| |
| // Pointers to templates. |
| // Expected rewrite: raw_ptr<std::string> string_ptr; |
| std::string* string_ptr; |
| // Expected rewrite: raw_ptr<std::vector<char>> vector_ptr; |
| std::vector<char>* vector_ptr; |
| // Expected rewrite: raw_ptr<SomeTemplate<char>> template_ptr; |
| SomeTemplate<char>* template_ptr; |
| |
| // Some types may be spelled in various, alternative ways. If possible, the |
| // rewriter should preserve the original spelling. |
| // |
| // Spelling of integer types. |
| // |
| // Expected rewrite: raw_ptr<int> ... |
| int* int_spelling1; |
| // Expected rewrite: raw_ptr<signed int> ... |
| // TODO(lukasza): Fix? Today this is rewritten into: raw_ptr<int> ... |
| signed int* int_spelling2; |
| // Expected rewrite: raw_ptr<long int> ... |
| // TODO(lukasza): Fix? Today this is rewritten into: raw_ptr<long> ... |
| long int* int_spelling3; |
| // Expected rewrite: raw_ptr<unsigned> ... |
| // TODO(lukasza): Fix? Today this is rewritten into: raw_ptr<unsigned int> |
| unsigned* int_spelling4; |
| // Expected rewrite: raw_ptr<int32_t> ... |
| int32_t* int_spelling5; |
| // Expected rewrite: raw_ptr<int64_t> ... |
| int64_t* int_spelling6; |
| // Expected rewrite: raw_ptr<int_fast32_t> ... |
| int_fast32_t* int_spelling7; |
| // |
| // Spelling of structs and classes. |
| // |
| // Expected rewrite: raw_ptr<SomeClass> ... |
| SomeClass* class_spelling1; |
| // Expected rewrite: raw_ptr<class SomeClass> ... |
| class SomeClass* class_spelling2; |
| // Expected rewrite: raw_ptr<my_namespace::SomeClass> ... |
| my_namespace::SomeClass* class_spelling3; |
| |
| // No rewrite of function pointers expected, because they won't ever be either |
| // A) allocated by PartitionAlloc or B) derived from RawPtrSupport. In |
| // theory |member_data_ptr| below can be A or B, but it can't be expressed as |
| // non-pointer T used as a template argument of raw_ptr<>. |
| int (*func_ptr)(); |
| void (SomeClass::*member_func_ptr)(char); // ~ pointer to SomeClass::Method |
| int SomeClass::*member_data_ptr; // ~ pointer to SomeClass::data_member |
| typedef void (*func_ptr_typedef)(char); |
| func_ptr_typedef func_ptr_typedef_field; |
| |
| // Typedef-ed or type-aliased pointees should participate in the rewriting. No |
| // desugaring of the aliases is expected. |
| typedef SomeClass SomeClassTypedef; |
| using SomeClassAlias = SomeClass; |
| typedef void (*func_ptr_typedef2)(char); |
| // Expected rewrite: raw_ptr<SomeClassTypedef> ... |
| SomeClassTypedef* typedef_ptr; |
| // Expected rewrite: raw_ptr<SomeClassAlias> ... |
| SomeClassAlias* alias_ptr; |
| // Expected rewrite: raw_ptr<func_ptr_typedef2> ... |
| func_ptr_typedef2* ptr_to_function_ptr; |
| |
| // Typedefs and type alias definitions should not be rewritten. |
| // |
| // No rewrite expected (for now - in V1 we only rewrite field decls). |
| typedef SomeClass* SomeClassPtrTypedef; |
| // No rewrite expected (for now - in V1 we only rewrite field decls). |
| using SomeClassPtrAlias = SomeClass*; |
| |
| // Char pointer fields should be rewritten, unless they are on the |
| // --field-filter-file blocklist. |
| // |
| // Expected rewrite: raw_ptr<char>, etc. |
| char* char_ptr; |
| char16_t* char16_ptr; |
| wchar_t* wide_char_ptr; |
| uint8_t* unsigned_char_ptr; |
| int8_t* signed_char_ptr; |
| |
| // TODO(crbug.com/1381955) |const char| pointer fields are not supported yet. |
| // |
| // No rewrite expected (for now). |
| const char* const_char_ptr; |
| const char16_t* const_char16_ptr; |
| const wchar_t* const_wide_char_ptr; |
| |
| // Expected rewrite: raw_ptr<const uint8_t> const_unsigned_char_ptr; |
| const uint8_t* const_unsigned_char_ptr; |
| // Expected rewrite: raw_ptr<const int8_t> const_signed_char_ptr; |
| const int8_t* const_signed_char_ptr; |
| |
| // Expected rewrite: raw_ptr<const unsigned char> const_unsigned_char_ptr2; |
| const unsigned char* const_unsigned_char_ptr2; |
| // Expected rewrite: raw_ptr<const signed char> const_signed_char_ptr2; |
| const signed char* const_signed_char_ptr2; |
| |
| // Expected rewrite: raw_ptr<const char*> double_char_ptr1; |
| const char** double_char_ptr1; |
| // Expected rewrite: raw_ptr<const char16_t*> double_char_ptr2; |
| const char16_t** double_char_ptr2; |
| // Expected rewrite: raw_ptr<const wchar_t*> double_char_ptr3; |
| const wchar_t** double_char_ptr3; |
| // Expected rewrite: raw_ptr<const unsigned char*> double_char_ptr4; |
| const unsigned char** double_char_ptr4; |
| // Expected rewrite: raw_ptr<const signed char*> double_char_ptr5; |
| const signed char** double_char_ptr5; |
| |
| // |array_of_ptrs| is an array 123 of pointer to SomeClass. |
| // No rewrite expected (this is not a pointer - this is an array). |
| SomeClass* ptr_array[123]; |
| |
| // |ptr_to_array| is a pointer to array 123 of const SomeClass. |
| // |
| // This test is based on EqualsFramesMatcher from |
| // //net/websockets/websocket_channel_test.cc |
| // |
| // No rewrite expected (this *is* a pointer, but generating a correct |
| // replacement is tricky, because the |replacement_range| needs to cover |
| // "[123]" that comes *after* the field name). |
| const SomeClass (*ptr_to_array)[123]; |
| }; |
| |
| struct MyStruct2 { |
| // Expected rewrite: const raw_ref<bool> bool_ref; |
| bool& bool_ref; |
| // Expected rewrite: const raw_ref<const bool> bool_ref; |
| const bool& const_bool_ref; |
| |
| // Expected rewrite: const raw_ref<std::string> string_ref; |
| std::string& string_ref; |
| // Expected rewrite: const raw_ref<std::vector<char>> vector_ref; |
| std::vector<char>& vector_ref; |
| // Expected rewrite: const raw_ref<SomeTemplate<char>> template_ref; |
| SomeTemplate<char>& template_ref; |
| |
| // Some types may be spelled in various, alternative ways. If possible, the |
| // rewriter should preserve the original spelling. |
| // |
| // Spelling of integer types. |
| // |
| // Expected rewrite: const raw_ref<int> ... |
| int& int_spelling1; |
| // Expected rewrite: const raw_ref<signed int> ... |
| // Today this is rewritten into: const raw_ref<int> ... |
| signed int& int_spelling2; |
| // Expected rewrite: const raw_ref<long int> ... |
| // Today this is rewritten into: const raw_ref<long> ... |
| long int& int_spelling3; |
| // Expected rewrite: const raw_ref<unsigned> ... |
| // Today this is rewritten into: const raw_ref<unsigned int> |
| unsigned& int_spelling4; |
| // Expected rewrite: const raw_ref<int32_t> ... |
| int32_t& int_spelling5; |
| // Expected rewrite: const raw_ref<int64_t> ... |
| int64_t& int_spelling6; |
| // Expected rewrite: const raw_ref<int_fast32_t> ... |
| int_fast32_t& int_spelling7; |
| // |
| // Spelling of structs and classes. |
| // |
| // Expected rewrite: const raw_ref<SomeClass> ... |
| SomeClass& class_spelling1; |
| // Expected rewrite: const raw_ref<class SomeClass> ... |
| class SomeClass& class_spelling2; |
| // Expected rewrite: const raw_ref<my_namespace::SomeClass> ... |
| my_namespace::SomeClass& class_spelling3; |
| |
| // Typedef-ed or type-aliased pointees should participate in the rewriting. No |
| // desugaring of the aliases is expected. |
| typedef SomeClass SomeClassTypedef; |
| using SomeClassAlias = SomeClass; |
| typedef void (*func_ptr_typedef2)(char); |
| // Expected rewrite: const raw_ref<SomeClassTypedef> ... |
| SomeClassTypedef& typedef_ref; |
| // Expected rewrite: const raw_ref<SomeClassAlias> ... |
| SomeClassAlias& alias_ref; |
| // Expected rewrite: const raw_ref<func_ptr_typedef2> ... |
| func_ptr_typedef2& ref_to_function_ptr; |
| |
| // Typedefs and type alias definitions should not be rewritten. |
| // |
| // No rewrite expected (for now - in V1 we only rewrite field decls). |
| typedef SomeClass& SomeClassRefTypedef; |
| // No rewrite expected (for now - in V1 we only rewrite field decls). |
| using SomeClassRefAlias = SomeClass&; |
| |
| // Char pointer fields should be rewritten, unless they are on the |
| // --field-filter-file blocklist. |
| // |
| // Expected rewrite: const raw_ref<char>, etc. |
| char& char_ref; |
| const char& const_char_ref; |
| wchar_t& wide_char_ref; |
| const wchar_t& const_wide_char_ref; |
| }; |
| |
| extern "C" { |
| struct OtherForeignStruct; |
| struct ForeignStruct { |
| // We should not rewrite foreign, extern "C" structs. |
| OtherForeignStruct* ptr; |
| OtherForeignStruct& ref; |
| }; |
| } |
| |
| } // namespace my_namespace |