Coverage for /Syzygy/refinery/types/type.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
0.0%00386.C++source

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    :  #ifndef SYZYGY_REFINERY_TYPES_TYPE_H_
  16    :  #define SYZYGY_REFINERY_TYPES_TYPE_H_
  17    :  
  18    :  #include <stdint.h>
  19    :  #include <functional>
  20    :  #include <vector>
  21    :  
  22    :  #include "base/logging.h"
  23    :  #include "base/macros.h"
  24    :  #include "base/memory/ref_counted.h"
  25    :  #include "base/strings/string16.h"
  26    :  
  27  m :  namespace refinery {
  28    :  
  29    :  // fwd.
  30  m :  class TypeRepository;
  31  m :  typedef size_t TypeId;
  32    :  
  33    :  // A sentinel value for uninitialized types.
  34  m :  const TypeId kNoTypeId = static_cast<TypeId>(-1);
  35  m :  const wchar_t kUnknownTypeName[] = L"<unknown>";
  36    :  
  37    :  // A base class for all Type subclasses. Types are owned by a type repository,
  38    :  // which can vend out type instances by ID on demand.
  39  m :  class Type : public base::RefCounted<Type> {
  40  m :   public:
  41  m :    typedef uint8_t Flags;
  42    :  
  43    :    // The set of type classes is closed, each type is enumerated here.
  44  m :    enum TypeKind {
  45  m :      BASIC_TYPE_KIND,
  46  m :      USER_DEFINED_TYPE_KIND,
  47  m :      POINTER_TYPE_KIND,
  48  m :      ARRAY_TYPE_KIND,
  49  m :      FUNCTION_TYPE_KIND,
  50  m :      GLOBAL_TYPE_KIND,
  51  m :      WILDCARD_TYPE_KIND,
  52  m :    };
  53    :  
  54  m :    enum CV_FLAGS {
  55  m :      FLAG_CONST        = 0x0001,
  56  m :      FLAG_VOLATILE     = 0x0002,
  57  m :    };
  58    :  
  59    :    // @name Accessors
  60    :    // @{
  61  m :    TypeRepository* repository() const { return repository_; }
  62  m :    TypeId type_id() const { return type_id_; }
  63  m :    size_t size() const { return size_; }
  64  m :    TypeKind kind() const { return kind_; }
  65    :    // @}
  66    :  
  67    :    // @returns the type's name or decorated name, or kUnknownTypeName.
  68  m :    virtual base::string16 GetName() const;
  69  m :    virtual base::string16 GetDecoratedName() const;
  70    :  
  71    :    // Safely down-cast this to @p SubType.
  72    :    // @param out the subtype to cast this to.
  73    :    // @returns true on success, false on failure.
  74  m :    template <class SubType>
  75  m :    bool CastTo(scoped_refptr<SubType>* out);
  76  m :    template <class SubType>
  77  m :    bool CastTo(scoped_refptr<const SubType>* out) const;
  78    :  
  79  m :   protected:
  80  m :    friend class base::RefCounted<Type>;
  81    :  
  82  m :    Type(TypeKind kind, size_t size);
  83  m :    virtual ~Type() = 0;
  84    :  
  85  m :   private:
  86  m :    friend class TypeRepository;
  87  m :    void SetRepository(TypeRepository* repository, TypeId type_id);
  88    :  
  89    :    // The type repository this type belongs to and its ID in the repository.
  90  m :    TypeRepository* repository_;
  91  m :    TypeId type_id_;
  92    :  
  93    :    // The kind of this type is, synonymous with its class.
  94  m :    const TypeKind kind_;
  95    :    // Size of type.
  96  m :    const size_t size_;
  97    :  
  98  m :    DISALLOW_COPY_AND_ASSIGN(Type);
  99  m :  };
 100    :  
 101  m :  using TypePtr = scoped_refptr<Type>;
 102  m :  using ConstTypePtr = scoped_refptr<const Type>;
 103    :  
 104    :  // Constant for no type flags.
 105  m :  const Type::Flags kNoTypeFlags = 0x0000;
 106    :  
 107    :  // Represents named types (basic types and user defined types).
 108    :  // TODO(manzagop): make it explicit whether the type has a decorated name (see
 109    :  // pdb's decorated_name_present).
 110  m :  class NamedType : public Type {
 111  m :   public:
 112  m :    base::string16 GetName() const override { return name_; }
 113  m :    base::string16 GetDecoratedName() const override { return decorated_name_; }
 114    :  
 115  m :   protected:
 116  m :    NamedType(TypeKind kind,
 117  m :              size_t size,
 118  m :              const base::string16& name,
 119  m :              const base::string16& decorated_name);
 120  m :    virtual ~NamedType() = 0;
 121    :  
 122  m :   private:
 123    :    // Name of type.
 124  m :    base::string16 name_;
 125    :    // Decorated name of type.
 126  m :    base::string16 decorated_name_;
 127    :  
 128  m :    DISALLOW_COPY_AND_ASSIGN(NamedType);
 129  m :  };
 130    :  
 131    :  // Represents a basic type, such as e.g. an int, char, void, etc.
 132  m :  class BasicType : public NamedType {
 133  m :   public:
 134  m :    static const TypeKind ID = BASIC_TYPE_KIND;
 135    :  
 136    :    // Creates a new basictype with name @p name and size @p size.
 137    :    // Sets decorated_name equal to name as basic types have no decorated names.
 138  m :    BasicType(const base::string16& name, size_t size);
 139    :  
 140  m :   private:
 141  m :    DISALLOW_COPY_AND_ASSIGN(BasicType);
 142  m :  };
 143    :  
 144  m :  using BasicTypePtr = scoped_refptr<BasicType>;
 145  m :  using ConstBasicTypePtr = scoped_refptr<const BasicType>;
 146    :  
 147    :  // Represents a user defined type such as a struct, union or a class. Also
 148    :  // represents forward references to such types.
 149  m :  class UserDefinedType : public NamedType {
 150  m :   public:
 151  m :    class Field;
 152  m :    class BaseClassField;
 153  m :    class MemberField;
 154  m :    class VfptrField;
 155  m :    class Function;
 156    :  
 157  m :    typedef std::vector<scoped_refptr<const Field>> Fields;
 158  m :    typedef std::vector<scoped_refptr<const BaseClassField>> BaseClasses;
 159  m :    typedef std::vector<scoped_refptr<const MemberField>> Members;
 160  m :    typedef std::vector<scoped_refptr<const VfptrField>> Vfptrs;
 161    :  
 162  m :    typedef std::vector<Function> Functions;
 163    :  
 164  m :    static const TypeKind ID = USER_DEFINED_TYPE_KIND;
 165    :  
 166  m :    enum UdtKind { UDT_CLASS, UDT_STRUCT, UDT_UNION };
 167    :  
 168    :    // Creates a new user defined type with name @p name, size @p size.
 169    :    // This creates an un-finalized UDT with no fields.
 170    :    // This will eventually be deleted.
 171  m :    UserDefinedType(const base::string16& name, size_t size, UdtKind udt_kind);
 172    :  
 173    :    // Creates a new user defined type with name @p name, decorated name @p
 174    :    // decorated_name and size @p size.
 175    :    // This creates an un-finalized UDT with no fields.
 176  m :    UserDefinedType(const base::string16& name,
 177  m :                    const base::string16& decorated_name,
 178  m :                    size_t size,
 179  m :                    UdtKind udt_kind);
 180    :  
 181    :    // Retrieves the type associated with field @p field_no.
 182    :    // @pre field_no < fields().size().
 183    :    // @pre SetRepository has been called.
 184  m :    TypePtr GetFieldType(size_t field_no) const;
 185    :  
 186    :    // Retrieves fields of a given kind.
 187    :    // @param fields on return, contains the matching fields.
 188  m :    template <class FieldType>
 189  m :    void GetFieldsOfKind(std::vector<scoped_refptr<const FieldType>>* fields);
 190    :  
 191    :    // Retrieves the type associated with function @p function_no.
 192    :    // @pre function_no < functions().size().
 193    :    // @pre SetRepository has been called.
 194  m :    TypePtr GetFunctionType(size_t function_no) const;
 195    :  
 196    :    // Accessors.
 197    :    // @{
 198  m :    const Fields& fields() const { return fields_; }
 199  m :    const Functions& functions() const { return functions_; }
 200  m :    bool is_fwd_decl() const { return is_fwd_decl_; }
 201  m :    UdtKind udt_kind() const { return udt_kind_; }
 202    :    // @}
 203    :  
 204    :    // Finalize the type by providing it with a field list.
 205    :    // @param fields the fields for the type (consumed).
 206    :    // @param functions the member functions for the type (consumed).
 207    :    // @note this can only be called once per type instance. Moreover this and
 208    :    //     setting the type as a forward declaration are mutually exclusive.
 209  m :    void Finalize(Fields* fields, Functions* functions);
 210    :  
 211    :    // Set this as forward declaration without concrete class.
 212    :    // @note this can only be called once per type instance. Moreover this and
 213    :    //     finalizing the UDT are mutually exclusive.
 214  m :    void SetIsForwardDeclaration();
 215    :  
 216  m :   private:
 217  m :    Fields fields_;
 218  m :    Functions functions_;
 219  m :    bool is_fwd_decl_;
 220  m :    UdtKind udt_kind_;
 221    :  
 222  m :    DISALLOW_COPY_AND_ASSIGN(UserDefinedType);
 223  m :  };
 224    :  
 225  m :  using UserDefinedTypePtr = scoped_refptr<UserDefinedType>;
 226  m :  using ConstUserDefinedTypePtr = scoped_refptr<const UserDefinedType>;
 227    :  
 228    :  // Represents a field in a user defined type.
 229    :  // TODO(manzagop): add virtual base classes?
 230  m :  class UserDefinedType::Field : public base::RefCounted<UserDefinedType::Field> {
 231  m :   public:
 232    :    // The set of field kinds.
 233  m :    enum FieldKind {
 234  m :      BASE_CLASS_KIND,
 235  m :      MEMBER_KIND,
 236  m :      VFPTR_KIND,
 237  m :    };
 238    :  
 239    :    // @name Accessors.
 240    :    // @{
 241  m :    FieldKind kind() const { return kind_; }
 242  m :    ptrdiff_t offset() const { return offset_; }
 243  m :    TypeId type_id() const { return type_id_; }
 244    :    // @}
 245    :  
 246  m :    TypePtr GetType() const;
 247    :  
 248    :    // Safely down-cast this to @p SubType.
 249    :    // @param out the subtype to cast this to.
 250    :    // @returns true on success, false on failure.
 251  m :    template <class SubType>
 252  m :    bool CastTo(scoped_refptr<SubType>* out);
 253  m :    template <class SubType>
 254  m :    bool CastTo(scoped_refptr<const SubType>* out) const;
 255    :  
 256  m :    bool operator==(const Field& o) const;
 257  m :    virtual bool IsEqual(const Field& o) const;
 258    :  
 259  m :   protected:
 260  m :    friend class base::RefCounted<UserDefinedType::Field>;
 261    :  
 262    :    // Creates a new field.
 263    :    // @param kind the kind of the field.
 264    :    // @param offset the byte offset of the field within the UDT.
 265    :    //    Note that many bitfield fields can share the same offset within a UDT,
 266    :    //    as can fields in a union.
 267    :    // @param type_id the type ID of the field.
 268    :    // @param repository the associated type repository.
 269  m :    Field(FieldKind kind,
 270  m :          ptrdiff_t offset,
 271  m :          TypeId type_id,
 272  m :          TypeRepository* repository);
 273  m :    virtual ~Field() = 0;
 274    :  
 275  m :    const FieldKind kind_;
 276  m :    const ptrdiff_t offset_;
 277  m :    const TypeId type_id_;
 278  m :    TypeRepository* repository_;
 279    :  
 280  m :   private:
 281  m :    DISALLOW_COPY_AND_ASSIGN(Field);
 282  m :  };
 283    :  
 284  m :  using FieldPtr = scoped_refptr<const UserDefinedType::Field>;
 285    :  
 286    :  // Represents a (non-virtual) base class field in a user defined type.
 287  m :  class UserDefinedType::BaseClassField : public UserDefinedType::Field{
 288  m :   public:
 289  m :    static const FieldKind ID = BASE_CLASS_KIND;
 290    :  
 291    :    // Creates a new base class field.
 292    :    // @param offset the byte offset of the field within the UDT.
 293    :    // @param type_id the type ID of the field.
 294    :    // @param repository the associated type repository.
 295  m :    BaseClassField(ptrdiff_t offset, TypeId type_id, TypeRepository* repository);
 296    :  
 297  m :   private:
 298  m :    friend class base::RefCounted<UserDefinedType::Field>;
 299  m :    ~BaseClassField() {}
 300    :  
 301  m :    DISALLOW_COPY_AND_ASSIGN(BaseClassField);
 302  m :  };
 303    :  
 304  m :  using BaseClassFieldPtr = scoped_refptr<const UserDefinedType::BaseClassField>;
 305    :  
 306    :  // Represents a member in a user defined type.
 307  m :  class UserDefinedType::MemberField : public UserDefinedType::Field {
 308  m :   public:
 309  m :    static const FieldKind ID = MEMBER_KIND;
 310    :  
 311    :    // Creates a new member field.
 312    :    // @param name the name of the field.
 313    :    // @param offset the byte offset of the field within the UDT.
 314    :    //    Note that many bitfield fields can share the same offset within a UDT,
 315    :    //    as can fields in a union.
 316    :    // @param flags any combination of Flags, denoting properties of the field.
 317    :    // @param bit_pos if this field is a bitfield, this is the bit position.
 318    :    // @param bit_len if this field is a bitfield, this is the bit length.
 319    :    // @param type_id the type ID of the field.
 320    :    // @param repository the associated type repository.
 321    :    // @note bit_pos and bit_len must be in the range 0..63.
 322    :    // @note When bit_len is zero it signifies that the field is not a bitfield.
 323  m :    MemberField(const base::string16& name,
 324  m :                ptrdiff_t offset,
 325  m :                Type::Flags flags,
 326  m :                size_t bit_pos,
 327  m :                size_t bit_len,
 328  m :                TypeId type_id,
 329  m :                TypeRepository* repository);
 330    :  
 331    :    // @name Accessors.
 332    :    // @{
 333  m :    const base::string16& name() const { return name_; }
 334  m :    size_t bit_pos() const { return bit_pos_; }
 335  m :    size_t bit_len() const { return bit_len_; }
 336  m :    bool is_const() const { return (flags_ & Type::FLAG_CONST) != 0; }
 337  m :    bool is_volatile() const { return (flags_ & Type::FLAG_VOLATILE) != 0; }
 338    :    // @}
 339    :  
 340  m :    bool IsEqual(const Field& o) const override;
 341    :  
 342  m :   private:
 343  m :    friend class base::RefCounted<UserDefinedType::Field>;
 344  m :    ~MemberField() {}
 345    :  
 346  m :    const base::string16 name_;
 347  m :    const Type::Flags flags_;
 348  m :    const size_t bit_pos_ : 6;
 349  m :    const size_t bit_len_ : 6;
 350    :  
 351  m :    DISALLOW_COPY_AND_ASSIGN(MemberField);
 352  m :  };
 353    :  
 354  m :  using MemberFieldPtr = scoped_refptr<const UserDefinedType::MemberField>;
 355    :  
 356    :  // Represents a virtual function pointer field in a user defined type.
 357  m :  class UserDefinedType::VfptrField : public UserDefinedType::Field{
 358  m :   public:
 359  m :    static const FieldKind ID = VFPTR_KIND;
 360    :  
 361    :    // Creates a new virtual function pointer field.
 362    :    // @param offset the byte offset of the field within the UDT.
 363    :    // @param type_id the type ID of the field.
 364    :    // @param repository the associated type repository.
 365  m :    VfptrField(ptrdiff_t offset, TypeId type_id, TypeRepository* repository);
 366    :  
 367  m :   private:
 368  m :    friend class base::RefCounted<UserDefinedType::Field>;
 369  m :    ~VfptrField() {}
 370    :  
 371  m :    DISALLOW_COPY_AND_ASSIGN(VfptrField);
 372  m :  };
 373    :  
 374  m :  using VfptrFieldPtr = scoped_refptr<const UserDefinedType::VfptrField>;
 375    :  
 376    :  // Represents a member function in UDT.
 377  m :  class UserDefinedType::Function {
 378  m :   public:
 379    :    // Creates a new member function.
 380    :    // @param name the name of the field.
 381    :    // @param type_id the type ID of the function type.
 382  m :    Function(const base::string16& name, TypeId type_id);
 383    :  
 384    :    // @name Accessors.
 385    :    // @{
 386  m :    const base::string16& name() const { return name_; }
 387  m :    TypeId type_id() const { return type_id_; }
 388    :    // @}
 389    :  
 390  m :    bool operator==(const Function& other) const;
 391    :  
 392  m :   private:
 393  m :    const base::string16 name_;
 394  m :    const TypeId type_id_;
 395  m :  };
 396    :  
 397    :  // Represents a pointer to some other type.
 398  m :  class PointerType : public Type {
 399  m :   public:
 400  m :    static const TypeKind ID = POINTER_TYPE_KIND;
 401    :  
 402    :    // Enum describing two pointer modes - regular pointer or reference.
 403  m :    enum Mode {
 404  m :      PTR_MODE_PTR = 0x00,
 405  m :      PTR_MODE_REF = 0x01,
 406  m :    };
 407    :  
 408    :    // Creates a new (non-finalized) pointer type with size @p size and value @p
 409    :    // ptr_mode which determines whether this is actually pointer or reference.
 410  m :    explicit PointerType(size_t size, Mode ptr_mode);
 411    :  
 412    :    // Accessors.
 413    :    // @{
 414  m :    TypeId content_type_id() const { return content_type_id_; }
 415  m :    bool is_const() const { return (flags_ & FLAG_CONST) != 0; }
 416  m :    bool is_volatile() const { return (flags_ & FLAG_VOLATILE) != 0; }
 417  m :    Mode ptr_mode() const { return ptr_mode_; }
 418    :    // @}
 419    :  
 420    :    // Retrieves the type this pointer refers to.
 421    :    // @pre SetRepository has been called.
 422  m :    TypePtr GetContentType() const;
 423    :  
 424    :    // Finalize the pointer type with @p flags and @p content_type_id.
 425  m :    void Finalize(Flags flags, TypeId content_type_id);
 426    :  
 427  m :   private:
 428    :    // Stores the CV qualifiers of the pointee.
 429  m :    Flags flags_;
 430    :    // Stores the type this pointer points to.
 431  m :    TypeId content_type_id_;
 432    :  
 433    :    // Determines whether this is a reference or an actual pointer.
 434  m :    Mode ptr_mode_;
 435  m :  };
 436    :  
 437  m :  using PointerTypePtr = scoped_refptr<PointerType>;
 438  m :  using ConstPointerTypePtr = scoped_refptr<const PointerType>;
 439    :  
 440    :  // Represents an array of some other type.
 441  m :  class ArrayType : public Type {
 442  m :   public:
 443  m :    static const TypeKind ID = ARRAY_TYPE_KIND;
 444    :  
 445  m :    explicit ArrayType(size_t size);
 446    :  
 447    :    // Accessors.
 448    :    // @{
 449  m :    TypeId index_type_id() const { return index_type_id_; }
 450  m :    size_t num_elements() const { return num_elements_; }
 451  m :    TypeId element_type_id() const { return element_type_id_; }
 452    :  
 453  m :    bool is_const() const { return (flags_ & FLAG_CONST) != 0; }
 454  m :    bool is_volatile() const { return (flags_ & FLAG_VOLATILE) != 0; }
 455    :    // @}
 456    :  
 457    :    // @name Retrieve the index/element types.
 458    :    // @pre SetRepository has been called.
 459    :    // @{
 460  m :    TypePtr GetIndexType() const;
 461  m :    TypePtr GetElementType() const;
 462    :    // @}
 463    :  
 464    :    // Finalize the array type.
 465  m :    void Finalize(Flags flags,
 466  m :                  TypeId index_type_id,
 467  m :                  size_t num_elements,
 468  m :                  TypeId element_type_id);
 469    :  
 470  m :   private:
 471    :    // The CV qualifiers for the elements.
 472  m :    Flags flags_;
 473    :  
 474    :    // The type ID for the the index type.
 475  m :    TypeId index_type_id_;
 476    :  
 477    :    // The number of elements in this array.
 478  m :    size_t num_elements_;
 479    :  
 480    :    // The type ID for the element type.
 481  m :    TypeId element_type_id_;
 482  m :  };
 483    :  
 484  m :  using ArrayTypePtr = scoped_refptr<ArrayType>;
 485  m :  using ConstArrayTypePtr = scoped_refptr<const ArrayType>;
 486    :  
 487    :  // Represents a function type.
 488  m :  class FunctionType : public Type {
 489  m :   public:
 490  m :    class ArgumentType {
 491  m :     public:
 492    :      // Creates a new argument.
 493    :      // @param flags any combination of Flags, denoting properties of the
 494    :      // argument.
 495    :      // @param type_id the type ID of the argument.
 496  m :      ArgumentType(Flags flags, TypeId type_id);
 497    :  
 498    :      // Default assignment operator.
 499  m :      ArgumentType& operator=(const ArgumentType&) = default;
 500    :  
 501    :      // @name Accessors.
 502    :      // @{
 503  m :      TypeId type_id() const { return type_id_; }
 504  m :      bool is_const() const { return (flags_ & FLAG_CONST) != 0; }
 505  m :      bool is_volatile() const { return (flags_ & FLAG_VOLATILE) != 0; }
 506    :      // @}
 507    :  
 508  m :      bool operator==(const ArgumentType& other) const;
 509    :  
 510  m :     private:
 511  m :      Flags flags_;
 512  m :      TypeId type_id_;
 513  m :    };
 514    :  
 515  m :    typedef std::vector<ArgumentType> Arguments;
 516  m :    enum CallConvention;
 517    :  
 518  m :    static const TypeKind ID = FUNCTION_TYPE_KIND;
 519    :  
 520    :    // Creates a new (non-finalized) function type.
 521    :    // @param call_convention calling convention of this function.
 522  m :    explicit FunctionType(CallConvention call_convention);
 523    :  
 524    :    // Retrieves the type associated with argument @p arg_no.
 525    :    // @pre arg_no < arguments().size().
 526    :    // @pre SetRepository has been called.
 527  m :    TypePtr GetArgumentType(size_t arg_no) const;
 528    :  
 529    :    // Retrieves the type associated with the return value.
 530    :    // @pre SetRepository has been called.
 531  m :    TypePtr GetReturnType() const;
 532    :  
 533    :    // Retrieves the type associated with the containing class.
 534    :    // @pre containing_class_id_ != kNoTypeId
 535    :    // @pre SetRepository has been called.
 536  m :    TypePtr GetContainingClassType() const;
 537    :  
 538    :    // @name Accessors.
 539    :    // @{
 540  m :    const Arguments& argument_types() const { return arg_types_; }
 541  m :    const CallConvention call_convention() const { return call_convention_; }
 542  m :    const TypeId containing_class_id() const { return containing_class_id_; }
 543  m :    const ArgumentType& return_type() const { return return_type_; }
 544    :    // @}
 545    :  
 546    :    // @returns true if this is a member function.
 547  m :    bool IsMemberFunction() const { return containing_class_id_ != kNoTypeId; }
 548    :  
 549    :    // Finalize the type by providing it with an argument list and return value.
 550    :    // @param return_value the return value of the type.
 551    :    // @param args the arguments for the type.
 552    :    // @param containing_class_id type index of the containing class.
 553    :    // @note this can only be called once per type instance.
 554  m :    void Finalize(const ArgumentType& return_type,
 555  m :                  const Arguments& arg_types,
 556  m :                  TypeId containing_class_id);
 557    :  
 558  m :   private:
 559    :    //  Stores the arguments.
 560  m :    Arguments arg_types_;
 561    :  
 562    :    // The return value.
 563  m :    ArgumentType return_type_;
 564    :  
 565    :    // The calling convention of this function.
 566  m :    CallConvention call_convention_;
 567    :  
 568    :    // The type index of the containing class or KNoTypeId if this is not a
 569    :    // member function.
 570  m :    TypeId containing_class_id_;
 571    :  
 572  m :    DISALLOW_COPY_AND_ASSIGN(FunctionType);
 573  m :  };
 574    :  
 575  m :  using FunctionTypePtr = scoped_refptr<FunctionType>;
 576  m :  using ConstFunctionTypePtr = scoped_refptr<const FunctionType>;
 577    :  
 578    :  // TODO(manzagop): determine whether global types have decorated names and if so
 579    :  //   store them, instead of duplicating the undecorated name.
 580  m :  class GlobalType : public NamedType {
 581  m :   public:
 582  m :    static const TypeKind ID = GLOBAL_TYPE_KIND;
 583    :  
 584    :    // TODO(siggi): Does it even make sense to have size here?
 585  m :    GlobalType(const base::string16& name,
 586  m :               uint64_t rva,
 587  m :               TypeId data_type_id,
 588  m :               size_t size);
 589    :  
 590    :    // @name Accessors.
 591    :    // @{
 592  m :    uint64_t rva() const { return rva_; }
 593  m :    TypeId data_type_id() const { return data_type_id_; }
 594    :    // @}
 595    :  
 596    :    // @name Retrieve the data type.
 597    :    // @pre SetRepository has been called.
 598  m :    TypePtr GetDataType() const;
 599    :  
 600  m :   private:
 601  m :    uint64_t rva_;
 602  m :    TypeId data_type_id_;
 603    :  
 604  m :    DISALLOW_COPY_AND_ASSIGN(GlobalType);
 605  m :  };
 606    :  
 607  m :  using GlobalTypePtr = scoped_refptr<GlobalType>;
 608  m :  using ConstGlobalTypePtr = scoped_refptr<const GlobalType>;
 609    :  
 610    :  // Enum representing different calling conventions, the values are the same as
 611    :  // the ones used in the PDB stream.
 612  m :  enum FunctionType::CallConvention {
 613  m :    CALL_NEAR_C = 0x00,
 614  m :    CALL_FAR_C = 0x01,
 615  m :    CALL_NEAR_PASCAL = 0x02,
 616  m :    CALL_FAR_PASCAL = 0x03,
 617  m :    CALL_NEAR_FASTCALL = 0x04,
 618  m :    CALL_FAR_FASTCALL = 0x05,
 619  m :    CALL_SKIPPED = 0x06,
 620  m :    CALL_NEAR_STDCALL = 0x07,
 621  m :    CALL_FAR_STDCALL = 0x08,
 622  m :    CALL_NEAR_SYSCALL = 0x09,
 623  m :    CALL_FAR_SYSCALL = 0x0A,
 624  m :    CALL_THIS_CALL = 0x0B,
 625  m :    CALL_MIPS_CALL = 0x0C,
 626  m :    CALL_GENERIC = 0x0D,
 627  m :    CALL_ALPHACALL = 0x0E,
 628  m :    CALL_PPCCALL = 0x0F,
 629  m :    CALL_SHCALL = 0x10,
 630  m :    CALL_ARMCALL = 0x11,
 631  m :    CALL_AM33CALL = 0x12,
 632  m :    CALL_TRICALL = 0x13,
 633  m :    CALL_SH5CALL = 0x14,
 634  m :    CALL_M32RCALL = 0x15,
 635  m :    CALL_CLRCALL = 0x16,
 636  m :    CALL_RESERVED = 0x17  // first unused call enumeration
 637  m :  };
 638    :  
 639    :  // Represents an otherwise unsupported type.
 640    :  // TODO(siggi): This is a stub, which needs to go away ASAP.
 641  m :  class WildcardType : public NamedType {
 642  m :   public:
 643  m :    static const TypeKind ID = WILDCARD_TYPE_KIND;
 644    :  
 645    :    // Creates a new wildcard type with name @p name, size @p size.
 646  m :    WildcardType(const base::string16& name, size_t size);
 647    :    // Creates a new wildcard type with name @p name, @p decorated_name and
 648    :    // size @p size.
 649  m :    WildcardType(const base::string16& name,
 650  m :                 const base::string16& decorated_name,
 651  m :                 size_t size);
 652  m :  };
 653    :  
 654  m :  using WildcardTypePtr = scoped_refptr<WildcardType>;
 655  m :  using ConstWildcardTypePtr = scoped_refptr<const WildcardType>;
 656    :  
 657  m :  template <class SubType>
 658  m :  bool Type::CastTo(scoped_refptr<SubType>* out) {
 659  m :    DCHECK(out);
 660  m :    if (SubType::ID != kind()) {
 661  m :      *out = nullptr;
 662  m :      return false;
 663  m :    }
 664    :  
 665  m :    *out = static_cast<SubType*>(this);
 666  m :    return true;
 667  m :  }
 668    :  
 669  m :  template <class SubType>
 670  m :  bool Type::CastTo(scoped_refptr<const SubType>* out) const {
 671  m :    DCHECK(out);
 672  m :    if (SubType::ID != kind()) {
 673  m :      *out = nullptr;
 674  m :      return false;
 675  m :    }
 676    :  
 677  m :    *out = static_cast<const SubType*>(this);
 678  m :    return true;
 679  m :  }
 680    :  
 681  m :  template <class FieldType>
 682  m :  void UserDefinedType::GetFieldsOfKind(
 683  m :      std::vector<scoped_refptr<const FieldType>>* fields) {
 684  m :    DCHECK(fields);
 685  m :    fields->clear();
 686    :  
 687  m :    for (auto field : fields_) {
 688  m :      scoped_refptr<const FieldType> casted_field;
 689  m :      if (field->CastTo(&casted_field)) {
 690  m :        DCHECK(casted_field.get() != nullptr);
 691  m :        fields->push_back(casted_field);
 692  m :      }
 693  m :    }
 694  m :  }
 695    :  
 696  m :  template <class SubType>
 697  m :  bool UserDefinedType::Field::CastTo(scoped_refptr<SubType>* out) {
 698  m :    DCHECK(out);
 699  m :    if (SubType::ID != kind()) {
 700  m :      *out = nullptr;
 701  m :      return false;
 702  m :    }
 703    :  
 704  m :    *out = static_cast<SubType*>(this);
 705  m :    return true;
 706  m :  }
 707    :  
 708  m :  template <class SubType>
 709  m :  bool UserDefinedType::Field::CastTo(scoped_refptr<const SubType>* out) const {
 710  m :    DCHECK(out);
 711  m :    if (SubType::ID != kind()) {
 712  m :      *out = nullptr;
 713  m :      return false;
 714  m :    }
 715    :  
 716  m :    *out = static_cast<const SubType*>(this);
 717  m :    return true;
 718  m :  }
 719    :  
 720  m :  }  // namespace refinery
 721    :  
 722    :  #endif  // SYZYGY_REFINERY_TYPES_TYPE_H_

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