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_
|