1=====================================
2CodeView Type Records
3=====================================
4
5
6.. contents::
7   :local:
8
9.. _types_intro:
10
11Introduction
12============
13
14This document describes the usage and serialization format of the various
15CodeView type records that LLVM understands.  This document does not describe
16every single CodeView type record that is defined.  In some cases, this is
17because the records are clearly deprecated and can only appear in very old
18software (e.g. the 16-bit types).  On other cases, it is because the records
19have never been observed in practice.  This could be because they are only
20generated for non-C++ code (e.g. Visual Basic, C#), or because they have been
21made obsolete by newer records, or any number of other reasons.  However, the
22records we describe here should cover 99% of type records that one can expect
23to encounter when dealing with modern C++ toolchains.
24
25Record Categories
26=================
27
28We can think of a sequence of CodeView type records as an array of variable length
29`leaf records`.  Each such record describes its own length as part of a fixed-size
30header, as well as the kind of record it is.  Leaf records are either padded to 4
31bytes (if this type stream appears in a TPI/IPI stream of a PDB) or not padded at
32all (if this type stream appears in the ``.debug$T`` section of an object file).
33Padding is implemented by inserting a decreasing sequence of `<_padding_records>`
34that terminates with ``LF_PAD0``.
35
36The final category of record is a ``member record``.  One particular leaf type --
37``LF_FIELDLIST`` -- contains a series of embedded records.  While the outer
38``LF_FIELDLIST`` describes its length (like any other leaf record), the embedded
39records -- called ``member records`` do not.
40
41.. _leaf_types:
42
43Leaf Records
44------------
45
46All leaf records begin with the following 4 byte prefix:
47
48.. code-block:: c++
49
50  struct RecordHeader {
51    uint16_t RecordLen;  // Record length, not including this 2 byte field.
52    uint16_t RecordKind; // Record kind enum.
53  };
54
55LF_POINTER (0x1002)
56^^^^^^^^^^^^^^^^^^^
57
58**Usage:** Describes a pointer to another type.
59
60**Layout:**
61
62.. code-block:: none
63
64  .--------------------.-- +0
65  |    Referent Type   |
66  .--------------------.-- +4
67  |     Attributes     |
68  .--------------------.-- +8
69  |  Member Ptr Info   |       Only present if |Attributes| indicates this is a member pointer.
70  .--------------------.-- +E
71
72Attributes is a bitfield with the following layout:
73
74.. code-block:: none
75
76    .-----------------------------------------------------------------------------------------------------.
77    |     Unused                   |  Flags  |       Size       |   Modifiers   |  Mode   |      Kind     |
78    .-----------------------------------------------------------------------------------------------------.
79    |                              |         |                  |               |         |               |
80   0x100                         +0x16     +0x13               +0xD            +0x8      +0x5            +0x0
81
82where the various fields are defined by the following enums:
83
84.. code-block:: c++
85
86  enum class PointerKind : uint8_t {
87    Near16 = 0x00,                // 16 bit pointer
88    Far16 = 0x01,                 // 16:16 far pointer
89    Huge16 = 0x02,                // 16:16 huge pointer
90    BasedOnSegment = 0x03,        // based on segment
91    BasedOnValue = 0x04,          // based on value of base
92    BasedOnSegmentValue = 0x05,   // based on segment value of base
93    BasedOnAddress = 0x06,        // based on address of base
94    BasedOnSegmentAddress = 0x07, // based on segment address of base
95    BasedOnType = 0x08,           // based on type
96    BasedOnSelf = 0x09,           // based on self
97    Near32 = 0x0a,                // 32 bit pointer
98    Far32 = 0x0b,                 // 16:32 pointer
99    Near64 = 0x0c                 // 64 bit pointer
100  };
101  enum class PointerMode : uint8_t {
102    Pointer = 0x00,                 // "normal" pointer
103    LValueReference = 0x01,         // "old" reference
104    PointerToDataMember = 0x02,     // pointer to data member
105    PointerToMemberFunction = 0x03, // pointer to member function
106    RValueReference = 0x04          // r-value reference
107  };
108  enum class PointerModifiers : uint8_t {
109    None = 0x00,                    // "normal" pointer
110    Flat32 = 0x01,                  // "flat" pointer
111    Volatile = 0x02,                // pointer is marked volatile
112    Const = 0x04,                   // pointer is marked const
113    Unaligned = 0x08,               // pointer is marked unaligned
114    Restrict = 0x10,                // pointer is marked restrict
115  };
116  enum class PointerFlags : uint8_t {
117    WinRTSmartPointer = 0x01,       // pointer is a WinRT smart pointer
118    LValueRefThisPointer = 0x02,    // pointer is a 'this' pointer of a member function with ref qualifier (e.g. void X::foo() &)
119    RValueRefThisPointer = 0x04     // pointer is a 'this' pointer of a member function with ref qualifier (e.g. void X::foo() &&)
120  };
121
122The ``Size`` field of the Attributes bitmask is a 1-byte value indicating the
123pointer size.  For example, a `void*` would have a size of either 4 or 8 depending
124on the target architecture.  On the other hand, if ``Mode`` indicates that this is
125a pointer to member function or pointer to data member, then the size can be any
126implementation defined number.
127
128The ``Member Ptr Info`` field of the ``LF_POINTER`` record is only present if the
129attributes indicate that this is a pointer to member.
130
131Note that "plain" pointers to primitive types are not represented by ``LF_POINTER``
132records, they are indicated by special reserved :ref:`TypeIndex values <type_indices>`.
133
134
135
136LF_MODIFIER (0x1001)
137^^^^^^^^^^^^^^^^^^^^
138
139LF_PROCEDURE (0x1008)
140^^^^^^^^^^^^^^^^^^^^^
141
142LF_MFUNCTION (0x1009)
143^^^^^^^^^^^^^^^^^^^^^
144
145LF_LABEL (0x000e)
146^^^^^^^^^^^^^^^^^
147
148LF_ARGLIST (0x1201)
149^^^^^^^^^^^^^^^^^^^
150
151LF_FIELDLIST (0x1203)
152^^^^^^^^^^^^^^^^^^^^^
153
154LF_ARRAY (0x1503)
155^^^^^^^^^^^^^^^^^
156
157LF_CLASS (0x1504)
158^^^^^^^^^^^^^^^^^
159
160LF_STRUCTURE (0x1505)
161^^^^^^^^^^^^^^^^^^^^^
162
163LF_INTERFACE (0x1519)
164^^^^^^^^^^^^^^^^^^^^^
165
166LF_UNION (0x1506)
167^^^^^^^^^^^^^^^^^
168
169LF_ENUM (0x1507)
170^^^^^^^^^^^^^^^^
171
172LF_TYPESERVER2 (0x1515)
173^^^^^^^^^^^^^^^^^^^^^^^
174
175LF_VFTABLE (0x151d)
176^^^^^^^^^^^^^^^^^^^
177
178LF_VTSHAPE (0x000a)
179^^^^^^^^^^^^^^^^^^^
180
181LF_BITFIELD (0x1205)
182^^^^^^^^^^^^^^^^^^^^
183
184LF_FUNC_ID (0x1601)
185^^^^^^^^^^^^^^^^^^^
186
187LF_MFUNC_ID (0x1602)
188^^^^^^^^^^^^^^^^^^^^
189
190LF_BUILDINFO (0x1603)
191^^^^^^^^^^^^^^^^^^^^^
192
193LF_SUBSTR_LIST (0x1604)
194^^^^^^^^^^^^^^^^^^^^^^^
195
196LF_STRING_ID (0x1605)
197^^^^^^^^^^^^^^^^^^^^^
198
199LF_UDT_SRC_LINE (0x1606)
200^^^^^^^^^^^^^^^^^^^^^^^^
201
202LF_UDT_MOD_SRC_LINE (0x1607)
203^^^^^^^^^^^^^^^^^^^^^^^^^^^^
204
205LF_METHODLIST (0x1206)
206^^^^^^^^^^^^^^^^^^^^^^
207
208LF_PRECOMP (0x1509)
209^^^^^^^^^^^^^^^^^^^
210
211LF_ENDPRECOMP (0x0014)
212^^^^^^^^^^^^^^^^^^^^^^
213
214.. _member_types:
215
216Member Records
217--------------
218
219LF_BCLASS (0x1400)
220^^^^^^^^^^^^^^^^^^
221
222LF_BINTERFACE (0x151a)
223^^^^^^^^^^^^^^^^^^^^^^
224
225LF_VBCLASS (0x1401)
226^^^^^^^^^^^^^^^^^^^
227
228LF_IVBCLASS (0x1402)
229^^^^^^^^^^^^^^^^^^^^
230
231LF_VFUNCTAB (0x1409)
232^^^^^^^^^^^^^^^^^^^^
233
234LF_STMEMBER (0x150e)
235^^^^^^^^^^^^^^^^^^^^
236
237LF_METHOD (0x150f)
238^^^^^^^^^^^^^^^^^^
239
240LF_MEMBER (0x150d)
241^^^^^^^^^^^^^^^^^^
242
243LF_NESTTYPE (0x1510)
244^^^^^^^^^^^^^^^^^^^^
245
246LF_ONEMETHOD (0x1511)
247^^^^^^^^^^^^^^^^^^^^^
248
249LF_ENUMERATE (0x1502)
250^^^^^^^^^^^^^^^^^^^^^
251
252LF_INDEX (0x1404)
253^^^^^^^^^^^^^^^^^
254
255.. _padding_records:
256
257Padding Records
258---------------
259
260LF_PADn (0xf0 + n)
261^^^^^^^^^^^^^^^^^^
262