1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/refinery/types/type.h"
16 :
17 : #include "base/memory/ref_counted.h"
18 : #include "gtest/gtest.h"
19 : #include "syzygy/refinery/types/type_repository.h"
20 :
21 m : namespace refinery {
22 :
23 m : namespace {
24 :
25 m : enum ConstQualifier {
26 m : NOT_CONST_QUALIFIED,
27 m : CONST_QUALIFIED
28 m : };
29 m : enum VolatileQualifier {
30 m : NOT_VOLATILE_QUALIFIED,
31 m : VOLATILE_QUALIFIED
32 m : };
33 :
34 m : class TypesTest : public testing::Test {
35 m : protected:
36 m : void SetUp() override {
37 m : Test::SetUp();
38 m : repo_ = new TypeRepository();
39 m : }
40 :
41 m : TypePtr CreatePointerType(size_t size,
42 m : PointerType::Mode ptr_mode,
43 m : Type::Flags flags,
44 m : TypeId content_type_id) {
45 m : PointerTypePtr ptr = new PointerType(size, ptr_mode);
46 m : ptr->Finalize(flags, content_type_id);
47 m : return ptr;
48 m : }
49 :
50 m : void ValidateMemberField(FieldPtr field,
51 m : const base::string16& name,
52 m : ptrdiff_t offset,
53 m : TypeId type_id,
54 m : ConstQualifier const_qualifier,
55 m : VolatileQualifier volatile_qualifier) {
56 m : EXPECT_EQ(offset, field->offset());
57 m : EXPECT_EQ(type_id, field->type_id());
58 m : MemberFieldPtr member;
59 m : ASSERT_TRUE(field->CastTo(&member)); // implicitely validates kind.
60 :
61 m : EXPECT_EQ(name, member->name());
62 m : EXPECT_EQ(const_qualifier == CONST_QUALIFIED, member->is_const());
63 m : EXPECT_EQ(volatile_qualifier == VOLATILE_QUALIFIED, member->is_volatile());
64 m : EXPECT_EQ(0U, member->bit_pos());
65 m : EXPECT_EQ(0U, member->bit_len());
66 m : }
67 :
68 m : scoped_refptr<TypeRepository> repo_;
69 m : };
70 :
71 m : } // namespace
72 :
73 m : TEST_F(TypesTest, BasicType) {
74 : // Create a BasicType and store in a supertype pointer.
75 m : TypePtr type = new BasicType(L"foo", 10);
76 :
77 m : ASSERT_TRUE(type.get());
78 : // Verify the kind and fields.
79 m : EXPECT_EQ(Type::BASIC_TYPE_KIND, type->kind());
80 m : EXPECT_EQ(L"foo", type->GetName());
81 m : EXPECT_EQ(L"foo", type->GetDecoratedName());
82 m : EXPECT_EQ(10U, type->size());
83 :
84 : // Down-cast it.
85 m : BasicTypePtr basic_type;
86 m : ASSERT_TRUE(type->CastTo(&basic_type));
87 m : ASSERT_TRUE(basic_type);
88 :
89 : // Verify that it can't be cast to a PointerType.
90 m : PointerTypePtr ptr;
91 m : EXPECT_FALSE(basic_type->CastTo(&ptr));
92 m : EXPECT_FALSE(ptr.get());
93 m : }
94 :
95 : // This test will eventually be deleted with the no-decorated-name constructor.
96 m : TEST_F(TypesTest, UserDefinedType) {
97 : // Build a UDT instance.
98 m : UserDefinedType::Fields fields;
99 :
100 m : const TypeId kBasicTypeId = repo_->AddType(new BasicType(L"int", 4));
101 m : fields.push_back(new UserDefinedType::MemberField(
102 m : L"one", 0, Type::FLAG_CONST, 0, 0, kBasicTypeId, repo_.get()));
103 m : fields.push_back(new UserDefinedType::MemberField(
104 m : L"two", 4, Type::FLAG_VOLATILE, 0, 0, kBasicTypeId, repo_.get()));
105 m : const TypeId kShortTypeId = repo_->AddType(new BasicType(L"short", 2));
106 m : fields.push_back(new UserDefinedType::MemberField(L"three", 8, 0, 0, 0,
107 m : kShortTypeId, repo_.get()));
108 m : UserDefinedTypePtr udt =
109 m : new UserDefinedType(L"foo", 10, UserDefinedType::UDT_CLASS);
110 :
111 m : const TypeId kClassId = repo_->AddType(udt);
112 :
113 : // Set up a member function.
114 m : FunctionTypePtr function = new FunctionType(FunctionType::CALL_NEAR_C);
115 m : function->Finalize(FunctionType::ArgumentType(kNoTypeFlags, kShortTypeId),
116 m : FunctionType::Arguments(), kClassId);
117 m : const TypeId kFunctionId = repo_->AddType(function);
118 :
119 m : UserDefinedType::Functions functions;
120 m : functions.push_back(
121 m : UserDefinedType::Function(L"memberFunction", kFunctionId));
122 :
123 m : udt->Finalize(&fields, &functions);
124 :
125 : // Up-cast it.
126 m : TypePtr type(udt);
127 m : udt = nullptr;
128 :
129 m : ASSERT_EQ(Type::USER_DEFINED_TYPE_KIND, type->kind());
130 m : EXPECT_EQ(L"foo", type->GetName());
131 m : EXPECT_EQ(L"foo", type->GetDecoratedName());
132 m : EXPECT_EQ(10, type->size());
133 :
134 m : ASSERT_TRUE(type->CastTo(&udt));
135 m : ASSERT_EQ(type.get(), udt.get());
136 :
137 m : EXPECT_FALSE(udt->is_fwd_decl());
138 m : EXPECT_EQ(UserDefinedType::UDT_CLASS, udt->udt_kind());
139 :
140 : // Verify the fields set up above.
141 m : ASSERT_EQ(3U, udt->fields().size());
142 :
143 m : ASSERT_NO_FATAL_FAILURE(ValidateMemberField(udt->fields()[0], L"one", 0U,
144 m : kBasicTypeId, CONST_QUALIFIED,
145 m : NOT_VOLATILE_QUALIFIED));
146 m : BasicTypePtr basic_type;
147 m : ASSERT_TRUE(udt->GetFieldType(0)->CastTo(&basic_type));
148 m : EXPECT_EQ(L"int", basic_type->GetName());
149 m : EXPECT_EQ(4, basic_type->size());
150 :
151 m : ASSERT_NO_FATAL_FAILURE(ValidateMemberField(udt->fields()[1], L"two", 4U,
152 m : kBasicTypeId, NOT_CONST_QUALIFIED,
153 m : VOLATILE_QUALIFIED));
154 m : ASSERT_TRUE(udt->GetFieldType(1)->CastTo(&basic_type));
155 m : EXPECT_EQ(L"int", basic_type->GetName());
156 m : EXPECT_EQ(4, basic_type->size());
157 :
158 m : ASSERT_NO_FATAL_FAILURE(ValidateMemberField(udt->fields()[2], L"three", 8U,
159 m : kShortTypeId, NOT_CONST_QUALIFIED,
160 m : NOT_VOLATILE_QUALIFIED));
161 m : ASSERT_TRUE(udt->GetFieldType(2)->CastTo(&basic_type));
162 m : EXPECT_EQ(L"short", basic_type->GetName());
163 m : EXPECT_EQ(2, basic_type->size());
164 :
165 m : EXPECT_EQ(1, udt->functions().size());
166 m : EXPECT_EQ(L"memberFunction", udt->functions()[0].name());
167 m : EXPECT_EQ(kFunctionId, udt->functions()[0].type_id());
168 m : ASSERT_TRUE(udt->GetFunctionType(0)->CastTo(&function));
169 m : EXPECT_EQ(L"short (foo::)()", function->GetName());
170 m : EXPECT_EQ(function->containing_class_id(), udt->type_id());
171 m : }
172 :
173 m : TEST_F(TypesTest, UserDefineTypeWithDecoratedName) {
174 : // Build a UDT instance.
175 m : UserDefinedType::Fields fields;
176 m : const TypeId kBasicTypeId = repo_->AddType(new BasicType(L"int", 4));
177 m : fields.push_back(new UserDefinedType::MemberField(
178 m : L"one", 0, Type::FLAG_CONST, 0, 0, kBasicTypeId, repo_.get()));
179 m : fields.push_back(new UserDefinedType::MemberField(
180 m : L"two", 4, Type::FLAG_VOLATILE, 0, 0, kBasicTypeId, repo_.get()));
181 m : const TypeId kShortTypeId = repo_->AddType(new BasicType(L"short", 2));
182 m : fields.push_back(new UserDefinedType::MemberField(L"three", 8, 0, 0, 0,
183 m : kShortTypeId, repo_.get()));
184 m : UserDefinedTypePtr udt = new UserDefinedType(L"foo", L"decorated_foo", 10,
185 m : UserDefinedType::UDT_STRUCT);
186 m : UserDefinedType::Functions functions;
187 m : udt->Finalize(&fields, &functions);
188 :
189 m : repo_->AddType(udt);
190 :
191 : // Up-cast it.
192 m : TypePtr type(udt);
193 m : udt = nullptr;
194 :
195 m : ASSERT_EQ(Type::USER_DEFINED_TYPE_KIND, type->kind());
196 m : EXPECT_EQ(L"foo", type->GetName());
197 m : EXPECT_EQ(L"decorated_foo", type->GetDecoratedName());
198 m : EXPECT_EQ(10, type->size());
199 :
200 m : ASSERT_TRUE(type->CastTo(&udt));
201 m : ASSERT_EQ(type.get(), udt.get());
202 :
203 m : EXPECT_FALSE(udt->is_fwd_decl());
204 m : EXPECT_EQ(UserDefinedType::UDT_STRUCT, udt->udt_kind());
205 :
206 : // Verify the fields set up above.
207 m : ASSERT_EQ(3U, udt->fields().size());
208 :
209 m : ASSERT_NO_FATAL_FAILURE(ValidateMemberField(udt->fields()[0], L"one", 0U,
210 m : kBasicTypeId, CONST_QUALIFIED,
211 m : NOT_VOLATILE_QUALIFIED));
212 m : BasicTypePtr basic_type;
213 m : ASSERT_TRUE(udt->GetFieldType(0)->CastTo(&basic_type));
214 m : EXPECT_EQ(L"int", basic_type->GetName());
215 m : EXPECT_EQ(4, basic_type->size());
216 :
217 m : ASSERT_NO_FATAL_FAILURE(ValidateMemberField(udt->fields()[1], L"two", 4U,
218 m : kBasicTypeId, NOT_CONST_QUALIFIED,
219 m : VOLATILE_QUALIFIED));
220 m : ASSERT_TRUE(udt->GetFieldType(1)->CastTo(&basic_type));
221 m : EXPECT_EQ(L"int", basic_type->GetName());
222 m : EXPECT_EQ(4, basic_type->size());
223 :
224 m : ASSERT_NO_FATAL_FAILURE(ValidateMemberField(udt->fields()[2], L"three", 8U,
225 m : kShortTypeId, NOT_CONST_QUALIFIED,
226 m : NOT_VOLATILE_QUALIFIED));
227 m : ASSERT_TRUE(udt->GetFieldType(2)->CastTo(&basic_type));
228 m : EXPECT_EQ(L"short", basic_type->GetName());
229 m : EXPECT_EQ(2, basic_type->size());
230 m : }
231 :
232 m : TEST_F(TypesTest, UserDefinedTypeGetFieldsOfKind) {
233 : // Create a basic type.
234 m : const TypeId kBasicTypeId = repo_->AddType(new BasicType(L"int", 4));
235 :
236 : // Create a UDT with a field.
237 m : UserDefinedType::Fields fields;
238 m : fields.push_back(new UserDefinedType::MemberField(
239 m : L"one", 0, Type::FLAG_CONST, 0, 0, kBasicTypeId, repo_.get()));
240 m : UserDefinedType::Functions functions;
241 m : UserDefinedTypePtr udt = new UserDefinedType(L"foo", L"decorated_foo", 4,
242 m : UserDefinedType::UDT_STRUCT);
243 m : udt->Finalize(&fields, &functions);
244 m : repo_->AddType(udt);
245 :
246 : // Retrieve fields.
247 m : UserDefinedType::Members members;
248 m : udt->GetFieldsOfKind(&members);
249 m : ASSERT_EQ(1, members.size());
250 m : ValidateMemberField(members[0], L"one", 0U, kBasicTypeId, CONST_QUALIFIED,
251 m : NOT_VOLATILE_QUALIFIED);
252 :
253 m : UserDefinedType::BaseClasses base_classes;
254 m : udt->GetFieldsOfKind(&base_classes);
255 m : ASSERT_EQ(0, base_classes.size());
256 m : }
257 :
258 m : TEST_F(TypesTest, UserDefineTypeForwardDeclaration) {
259 : // Build a UDT instance.
260 m : UserDefinedTypePtr udt = new UserDefinedType(L"fwd", L"decorated_fwd", 0,
261 m : UserDefinedType::UDT_STRUCT);
262 m : udt->SetIsForwardDeclaration();
263 :
264 m : repo_->AddType(udt);
265 :
266 : // Up-cast it.
267 m : TypePtr type(udt);
268 m : udt = nullptr;
269 :
270 m : ASSERT_EQ(Type::USER_DEFINED_TYPE_KIND, type->kind());
271 m : EXPECT_EQ(L"fwd", type->GetName());
272 m : EXPECT_EQ(L"decorated_fwd", type->GetDecoratedName());
273 m : EXPECT_EQ(0, type->size());
274 :
275 m : ASSERT_TRUE(type->CastTo(&udt));
276 m : ASSERT_EQ(type.get(), udt.get());
277 :
278 m : EXPECT_TRUE(udt->is_fwd_decl());
279 :
280 m : EXPECT_EQ(0, udt->fields().size());
281 m : EXPECT_EQ(0, udt->functions().size());
282 m : }
283 :
284 m : TEST(BaseClassFieldTest, BasicTest) {
285 m : scoped_refptr<TypeRepository> repository(new TypeRepository());
286 :
287 m : const TypeId id = 2;
288 m : const ptrdiff_t offset = 3;
289 :
290 m : BaseClassFieldPtr bclass_field =
291 m : new UserDefinedType::BaseClassField(offset, id, repository.get());
292 m : EXPECT_EQ(UserDefinedType::Field::BASE_CLASS_KIND, bclass_field->kind());
293 m : EXPECT_EQ(id, bclass_field->type_id());
294 m : EXPECT_EQ(offset, bclass_field->offset());
295 :
296 : // Validate IsEqual.
297 m : EXPECT_TRUE(bclass_field->IsEqual(*bclass_field));
298 m : BaseClassFieldPtr other_bclass_field =
299 m : new UserDefinedType::BaseClassField(offset + 1, id + 1, repository.get());
300 m : EXPECT_FALSE(bclass_field->IsEqual(*other_bclass_field));
301 m : }
302 :
303 m : TEST(VfptrFieldTest, BasicTest) {
304 m : scoped_refptr<TypeRepository> repository(new TypeRepository());
305 :
306 m : const TypeId id = 2;
307 m : const ptrdiff_t offset = 3;
308 :
309 m : VfptrFieldPtr vfptr_field =
310 m : new UserDefinedType::VfptrField(offset, id, repository.get());
311 m : EXPECT_EQ(UserDefinedType::Field::VFPTR_KIND, vfptr_field->kind());
312 m : EXPECT_EQ(id, vfptr_field->type_id());
313 m : EXPECT_EQ(offset, vfptr_field->offset());
314 :
315 : // Validate IsEqual.
316 m : EXPECT_TRUE(vfptr_field->IsEqual(*vfptr_field));
317 m : VfptrFieldPtr other_vfptr_field =
318 m : new UserDefinedType::VfptrField(offset + 1, id + 1, repository.get());
319 m : EXPECT_FALSE(vfptr_field->IsEqual(*other_vfptr_field));
320 m : }
321 :
322 m : TEST_F(TypesTest, PointerType) {
323 : // Build a Pointer instance.
324 m : const TypeId kPtrTypeId = repo_->AddType(new BasicType(L"void", 0));
325 m : TypePtr type = CreatePointerType(4, PointerType::PTR_MODE_PTR,
326 m : Type::FLAG_VOLATILE, kPtrTypeId);
327 m : repo_->AddType(type);
328 :
329 : // Test the basic properties.
330 m : ASSERT_TRUE(type);
331 m : EXPECT_EQ(L"void volatile*", type->GetName());
332 m : EXPECT_EQ(4U, type->size());
333 :
334 m : EXPECT_EQ(Type::POINTER_TYPE_KIND, type->kind());
335 :
336 : // Downcast and test its fields.
337 m : PointerTypePtr pointer;
338 m : ASSERT_TRUE(type->CastTo(&pointer));
339 m : ASSERT_TRUE(pointer);
340 m : EXPECT_FALSE(pointer->is_const());
341 m : EXPECT_TRUE(pointer->is_volatile());
342 m : EXPECT_EQ(PointerType::PTR_MODE_PTR, pointer->ptr_mode());
343 m : ASSERT_EQ(kPtrTypeId, pointer->content_type_id());
344 :
345 m : ASSERT_TRUE(pointer->GetContentType());
346 m : EXPECT_EQ(L"void", pointer->GetContentType()->GetName());
347 m : EXPECT_EQ(0U, pointer->GetContentType()->size());
348 m : }
349 :
350 m : TEST_F(TypesTest, PointerTypeWithDecoratedName) {
351 : // Build a Pointer instance.
352 m : const TypeId kPtrTypeId = repo_->AddType(new BasicType(L"void", 0));
353 m : PointerTypePtr ptr_type = new PointerType(4, PointerType::PTR_MODE_PTR);
354 m : ptr_type->Finalize(Type::FLAG_VOLATILE, kPtrTypeId);
355 :
356 m : TypePtr type = ptr_type;
357 m : repo_->AddType(type);
358 :
359 : // Test the basic properties.
360 m : ASSERT_TRUE(type);
361 m : EXPECT_EQ(L"void volatile*", type->GetName());
362 m : EXPECT_EQ(L"void volatile*", type->GetDecoratedName());
363 m : EXPECT_EQ(4U, type->size());
364 :
365 m : EXPECT_EQ(Type::POINTER_TYPE_KIND, type->kind());
366 :
367 : // Downcast and test its fields.
368 m : PointerTypePtr pointer;
369 m : ASSERT_TRUE(type->CastTo(&pointer));
370 m : ASSERT_TRUE(pointer);
371 m : EXPECT_FALSE(pointer->is_const());
372 m : EXPECT_TRUE(pointer->is_volatile());
373 m : EXPECT_EQ(PointerType::PTR_MODE_PTR, pointer->ptr_mode());
374 m : ASSERT_EQ(kPtrTypeId, pointer->content_type_id());
375 :
376 m : ASSERT_TRUE(pointer->GetContentType());
377 m : EXPECT_EQ(L"void", pointer->GetContentType()->GetName());
378 m : EXPECT_EQ(L"void", pointer->GetContentType()->GetDecoratedName());
379 m : EXPECT_EQ(0U, pointer->GetContentType()->size());
380 m : }
381 :
382 m : TEST_F(TypesTest, ArrayType) {
383 m : TypePtr int_type = new BasicType(L"int32_t", 0);
384 m : const TypeId kIntTypeId = repo_->AddType(int_type);
385 m : PointerTypePtr ptr_type = new PointerType(4, PointerType::PTR_MODE_PTR);
386 m : ptr_type->Finalize(Type::FLAG_VOLATILE, kIntTypeId);
387 m : const TypeId kPtrTypeId = repo_->AddType(ptr_type);
388 :
389 m : ArrayTypePtr array = new ArrayType(10 * ptr_type->size());
390 m : repo_->AddType(array);
391 m : array->Finalize(Type::FLAG_CONST, kIntTypeId, 10, kPtrTypeId);
392 :
393 m : ASSERT_EQ(kIntTypeId, array->index_type_id());
394 m : ASSERT_EQ(10, array->num_elements());
395 m : ASSERT_EQ(kPtrTypeId, array->element_type_id());
396 m : ASSERT_EQ(int_type, array->GetIndexType());
397 m : ASSERT_EQ(ptr_type, array->GetElementType());
398 m : ASSERT_EQ(ptr_type, array->GetElementType());
399 m : ASSERT_EQ(L"int32_t volatile* const[10]", array->GetName());
400 m : ASSERT_EQ(L"int32_t volatile* const[10]", array->GetDecoratedName());
401 m : ASSERT_FALSE(array->is_volatile());
402 m : }
403 :
404 m : TEST_F(TypesTest, FunctionType) {
405 : // Build a UDT instance.
406 m : FunctionType::Arguments args;
407 m : const TypeId kBasicTypeId = repo_->AddType(new BasicType(L"uint32_t", 4));
408 m : args.push_back(FunctionType::ArgumentType(Type::FLAG_CONST, kBasicTypeId));
409 m : args.push_back(FunctionType::ArgumentType(Type::FLAG_VOLATILE, kBasicTypeId));
410 m : const TypeId kShortTypeId = repo_->AddType(new BasicType(L"short", 2));
411 m : args.push_back(FunctionType::ArgumentType(kNoTypeFlags, kShortTypeId));
412 :
413 m : const TypeId kBoolTypeId = repo_->AddType(new BasicType(L"bool", 1));
414 m : FunctionType::ArgumentType ret_value(Type::FLAG_CONST, kBoolTypeId);
415 :
416 m : const TypeId kClassType = repo_->AddType(new UserDefinedType(
417 m : L"foo", L"decorated_foo", 10, UserDefinedType::UDT_CLASS));
418 :
419 m : FunctionTypePtr function = new FunctionType(FunctionType::CALL_NEAR_C);
420 m : function->Finalize(ret_value, args, kClassType);
421 :
422 m : repo_->AddType(function);
423 :
424 : // Up-cast it.
425 m : TypePtr type(function);
426 m : function = nullptr;
427 :
428 m : ASSERT_EQ(Type::FUNCTION_TYPE_KIND, type->kind());
429 m : EXPECT_EQ(L"bool const (foo::)(uint32_t const, uint32_t volatile, short)",
430 m : type->GetName());
431 m : EXPECT_EQ(
432 m : L"bool const (decorated_foo::)(uint32_t const, uint32_t volatile, short)",
433 m : type->GetDecoratedName());
434 m : EXPECT_EQ(0, type->size());
435 :
436 m : ASSERT_TRUE(type->CastTo(&function));
437 m : ASSERT_EQ(type.get(), function.get());
438 :
439 : // Verify the arguments set up above.
440 m : ASSERT_EQ(3U, function->argument_types().size());
441 :
442 m : EXPECT_EQ(FunctionType::CALL_NEAR_C, function->call_convention());
443 m : EXPECT_TRUE(function->IsMemberFunction());
444 m : EXPECT_EQ(kClassType, function->containing_class_id());
445 :
446 m : UserDefinedTypePtr udt;
447 m : EXPECT_TRUE(function->GetContainingClassType()->CastTo(&udt));
448 m : EXPECT_EQ(L"foo", udt->GetName());
449 m : EXPECT_EQ(L"decorated_foo", udt->GetDecoratedName());
450 :
451 m : EXPECT_TRUE(function->argument_types()[0].is_const());
452 m : EXPECT_FALSE(function->argument_types()[0].is_volatile());
453 m : EXPECT_EQ(kBasicTypeId, function->argument_types()[0].type_id());
454 m : BasicTypePtr basic_type;
455 m : ASSERT_TRUE(function->GetArgumentType(0)->CastTo(&basic_type));
456 m : EXPECT_EQ(L"uint32_t", basic_type->GetName());
457 m : EXPECT_EQ(4, basic_type->size());
458 :
459 m : EXPECT_FALSE(function->argument_types()[1].is_const());
460 m : EXPECT_TRUE(function->argument_types()[1].is_volatile());
461 m : EXPECT_EQ(kBasicTypeId, function->argument_types()[1].type_id());
462 m : ASSERT_TRUE(function->GetArgumentType(1)->CastTo(&basic_type));
463 m : EXPECT_EQ(L"uint32_t", basic_type->GetName());
464 m : EXPECT_EQ(4, basic_type->size());
465 :
466 m : EXPECT_FALSE(function->argument_types()[2].is_const());
467 m : EXPECT_FALSE(function->argument_types()[2].is_volatile());
468 m : EXPECT_EQ(kShortTypeId, function->argument_types()[2].type_id());
469 m : ASSERT_TRUE(function->GetArgumentType(2)->CastTo(&basic_type));
470 m : EXPECT_EQ(L"short", basic_type->GetName());
471 m : EXPECT_EQ(2, basic_type->size());
472 :
473 m : EXPECT_TRUE(function->return_type().is_const());
474 m : EXPECT_FALSE(function->return_type().is_volatile());
475 m : EXPECT_EQ(kBoolTypeId, function->return_type().type_id());
476 m : ASSERT_TRUE(function->GetReturnType()->CastTo(&basic_type));
477 m : EXPECT_EQ(L"bool", basic_type->GetName());
478 m : EXPECT_EQ(1, basic_type->size());
479 m : }
480 :
481 m : TEST_F(TypesTest, GlobalType) {
482 m : const TypeId kBasicTypeId = repo_->AddType(new BasicType(L"int", 4));
483 m : uint64_t kRVA = 0xCAFEBABE;
484 m : TypePtr type = new GlobalType(L"foo", kRVA, kBasicTypeId, 4);
485 m : EXPECT_EQ(Type::GLOBAL_TYPE_KIND, type->kind());
486 m : EXPECT_EQ(L"foo", type->GetName());
487 m : EXPECT_EQ(4, type->size());
488 :
489 m : ASSERT_NE(0U, repo_->AddType(type));
490 :
491 : // Cast it down.
492 m : GlobalTypePtr global;
493 m : ASSERT_TRUE(type->CastTo(&global));
494 :
495 m : EXPECT_EQ(kRVA, global->rva());
496 m : EXPECT_EQ(kBasicTypeId, global->data_type_id());
497 :
498 m : TypePtr data_type = global->GetDataType();
499 m : ASSERT_NE(nullptr, data_type);
500 m : EXPECT_EQ(L"int", data_type->GetName());
501 m : }
502 :
503 m : TEST_F(TypesTest, WildcardType) {
504 : // Build a wildcard instance.
505 m : TypePtr type = new WildcardType(L"Wildcard", 4);
506 m : repo_->AddType(type);
507 :
508 : // Test the basic properties.
509 m : ASSERT_TRUE(type);
510 m : EXPECT_EQ(L"Wildcard", type->GetName());
511 m : EXPECT_EQ(L"Wildcard", type->GetDecoratedName());
512 m : EXPECT_EQ(4U, type->size());
513 :
514 : // Downcast and test its fields.
515 m : WildcardTypePtr wildcard;
516 m : ASSERT_TRUE(type->CastTo(&wildcard));
517 m : ASSERT_TRUE(wildcard);
518 m : }
519 :
520 m : } // namespace refinery
|