Coverage for /Syzygy/refinery/types/type_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
0.0%00374.C++test

Line-by-line coverage:

   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

Coverage information generated Fri Jul 29 11:00:21 2016.