Bug Summary

File:lib/ObjectYAML/CodeViewYAMLTypes.cpp
Warning:line 591, column 51
The left operand of '==' is a garbage value

Annotated Source Code

/build/llvm-toolchain-snapshot-6.0~svn318601/lib/ObjectYAML/CodeViewYAMLTypes.cpp

1//===- CodeViewYAMLTypes.cpp - CodeView YAMLIO types implementation -------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines classes for handling the YAML representation of CodeView
11// Debug Info.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
16#include "llvm/ADT/APSInt.h"
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/BinaryFormat/COFF.h"
20#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
21#include "llvm/DebugInfo/CodeView/CodeView.h"
22#include "llvm/DebugInfo/CodeView/CodeViewError.h"
23#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
24#include "llvm/DebugInfo/CodeView/TypeIndex.h"
25#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
26#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
27#include "llvm/Support/Allocator.h"
28#include "llvm/Support/BinaryStreamReader.h"
29#include "llvm/Support/BinaryStreamWriter.h"
30#include "llvm/Support/Endian.h"
31#include "llvm/Support/Error.h"
32#include "llvm/Support/ErrorHandling.h"
33#include "llvm/Support/YAMLTraits.h"
34#include "llvm/Support/raw_ostream.h"
35#include <algorithm>
36#include <cassert>
37#include <cstdint>
38#include <vector>
39
40using namespace llvm;
41using namespace llvm::codeview;
42using namespace llvm::CodeViewYAML;
43using namespace llvm::CodeViewYAML::detail;
44using namespace llvm::yaml;
45
46LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<OneMethodRecord>::value && !std::is_same<OneMethodRecord
, std::string>::value && !std::is_same<OneMethodRecord
, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<OneMethodRecord
> { static const bool flow = false; }; } }
47LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<VFTableSlotKind>::value && !std::is_same<VFTableSlotKind
, std::string>::value && !std::is_same<VFTableSlotKind
, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<VFTableSlotKind
> { static const bool flow = false; }; } }
48LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<TypeIndex>::value && !std::is_same<TypeIndex
, std::string>::value && !std::is_same<TypeIndex
, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<TypeIndex
> { static const bool flow = true; }; } }
49
50LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false)namespace llvm { namespace yaml { template <> struct ScalarTraits
<TypeIndex> { static void output(const TypeIndex &Value
, void *ctx, raw_ostream &Out); static StringRef input(StringRef
Scalar, void *ctxt, TypeIndex &Value); static bool mustQuote
(StringRef) { return false; } }; } }
51LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false)namespace llvm { namespace yaml { template <> struct ScalarTraits
<APSInt> { static void output(const APSInt &Value, void
*ctx, raw_ostream &Out); static StringRef input(StringRef
Scalar, void *ctxt, APSInt &Value); static bool mustQuote
(StringRef) { return false; } }; } }
52
53LLVM_YAML_DECLARE_ENUM_TRAITS(TypeLeafKind)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<TypeLeafKind> { static void enumeration(IO &io, TypeLeafKind
&Value); }; } }
54LLVM_YAML_DECLARE_ENUM_TRAITS(PointerToMemberRepresentation)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<PointerToMemberRepresentation> { static void enumeration
(IO &io, PointerToMemberRepresentation &Value); }; } }
55LLVM_YAML_DECLARE_ENUM_TRAITS(VFTableSlotKind)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<VFTableSlotKind> { static void enumeration(IO &io,
VFTableSlotKind &Value); }; } }
56LLVM_YAML_DECLARE_ENUM_TRAITS(CallingConvention)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<CallingConvention> { static void enumeration(IO &io
, CallingConvention &Value); }; } }
57LLVM_YAML_DECLARE_ENUM_TRAITS(PointerKind)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<PointerKind> { static void enumeration(IO &io, PointerKind
&Value); }; } }
58LLVM_YAML_DECLARE_ENUM_TRAITS(PointerMode)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<PointerMode> { static void enumeration(IO &io, PointerMode
&Value); }; } }
59LLVM_YAML_DECLARE_ENUM_TRAITS(HfaKind)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<HfaKind> { static void enumeration(IO &io, HfaKind
&Value); }; } }
60LLVM_YAML_DECLARE_ENUM_TRAITS(MemberAccess)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<MemberAccess> { static void enumeration(IO &io, MemberAccess
&Value); }; } }
61LLVM_YAML_DECLARE_ENUM_TRAITS(MethodKind)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<MethodKind> { static void enumeration(IO &io, MethodKind
&Value); }; } }
62LLVM_YAML_DECLARE_ENUM_TRAITS(WindowsRTClassKind)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<WindowsRTClassKind> { static void enumeration(IO &
io, WindowsRTClassKind &Value); }; } }
63LLVM_YAML_DECLARE_ENUM_TRAITS(LabelType)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<LabelType> { static void enumeration(IO &io, LabelType
&Value); }; } }
64
65LLVM_YAML_DECLARE_BITSET_TRAITS(PointerOptions)namespace llvm { namespace yaml { template <> struct ScalarBitSetTraits
<PointerOptions> { static void bitset(IO &IO, PointerOptions
&Options); }; } }
66LLVM_YAML_DECLARE_BITSET_TRAITS(ModifierOptions)namespace llvm { namespace yaml { template <> struct ScalarBitSetTraits
<ModifierOptions> { static void bitset(IO &IO, ModifierOptions
&Options); }; } }
67LLVM_YAML_DECLARE_BITSET_TRAITS(FunctionOptions)namespace llvm { namespace yaml { template <> struct ScalarBitSetTraits
<FunctionOptions> { static void bitset(IO &IO, FunctionOptions
&Options); }; } }
68LLVM_YAML_DECLARE_BITSET_TRAITS(ClassOptions)namespace llvm { namespace yaml { template <> struct ScalarBitSetTraits
<ClassOptions> { static void bitset(IO &IO, ClassOptions
&Options); }; } }
69LLVM_YAML_DECLARE_BITSET_TRAITS(MethodOptions)namespace llvm { namespace yaml { template <> struct ScalarBitSetTraits
<MethodOptions> { static void bitset(IO &IO, MethodOptions
&Options); }; } }
70
71LLVM_YAML_DECLARE_MAPPING_TRAITS(OneMethodRecord)namespace llvm { namespace yaml { template <> struct MappingTraits
<OneMethodRecord> { static void mapping(IO &IO, OneMethodRecord
&Obj); }; } }
72LLVM_YAML_DECLARE_MAPPING_TRAITS(MemberPointerInfo)namespace llvm { namespace yaml { template <> struct MappingTraits
<MemberPointerInfo> { static void mapping(IO &IO, MemberPointerInfo
&Obj); }; } }
73
74namespace llvm {
75namespace CodeViewYAML {
76namespace detail {
77
78struct LeafRecordBase {
79 TypeLeafKind Kind;
80
81 explicit LeafRecordBase(TypeLeafKind K) : Kind(K) {}
82 virtual ~LeafRecordBase() = default;
83
84 virtual void map(yaml::IO &io) = 0;
85 virtual CVType toCodeViewRecord(TypeTableBuilder &TTB) const = 0;
86 virtual Error fromCodeViewRecord(CVType Type) = 0;
87};
88
89template <typename T> struct LeafRecordImpl : public LeafRecordBase {
90 explicit LeafRecordImpl(TypeLeafKind K)
91 : LeafRecordBase(K), Record(static_cast<TypeRecordKind>(K)) {}
92
93 void map(yaml::IO &io) override;
94
95 Error fromCodeViewRecord(CVType Type) override {
96 return TypeDeserializer::deserializeAs<T>(Type, Record);
97 }
98
99 CVType toCodeViewRecord(TypeTableBuilder &TTB) const override {
100 TTB.writeKnownType(Record);
101 return CVType(Kind, TTB.records().back());
102 }
103
104 mutable T Record;
105};
106
107template <> struct LeafRecordImpl<FieldListRecord> : public LeafRecordBase {
108 explicit LeafRecordImpl(TypeLeafKind K) : LeafRecordBase(K) {}
109
110 void map(yaml::IO &io) override;
111 CVType toCodeViewRecord(TypeTableBuilder &TTB) const override;
112 Error fromCodeViewRecord(CVType Type) override;
113
114 std::vector<MemberRecord> Members;
115};
116
117struct MemberRecordBase {
118 TypeLeafKind Kind;
119
120 explicit MemberRecordBase(TypeLeafKind K) : Kind(K) {}
121 virtual ~MemberRecordBase() = default;
122
123 virtual void map(yaml::IO &io) = 0;
124 virtual void writeTo(FieldListRecordBuilder &FLRB) = 0;
125};
126
127template <typename T> struct MemberRecordImpl : public MemberRecordBase {
128 explicit MemberRecordImpl(TypeLeafKind K)
129 : MemberRecordBase(K), Record(static_cast<TypeRecordKind>(K)) {}
130
131 void map(yaml::IO &io) override;
132
133 void writeTo(FieldListRecordBuilder &FLRB) override {
134 FLRB.writeMemberType(Record);
135 }
136
137 mutable T Record;
138};
139
140} // end namespace detail
141} // end namespace CodeViewYAML
142} // end namespace llvm
143
144void ScalarTraits<GUID>::output(const GUID &G, void *, llvm::raw_ostream &OS) {
145 OS << G;
146}
147
148StringRef ScalarTraits<GUID>::input(StringRef Scalar, void *Ctx, GUID &S) {
149 if (Scalar.size() != 38)
150 return "GUID strings are 38 characters long";
151 if (Scalar[0] != '{' || Scalar[37] != '}')
152 return "GUID is not enclosed in {}";
153 if (Scalar[9] != '-' || Scalar[14] != '-' || Scalar[19] != '-' ||
154 Scalar[24] != '-')
155 return "GUID sections are not properly delineated with dashes";
156
157 uint8_t *OutBuffer = S.Guid;
158 for (auto Iter = Scalar.begin(); Iter != Scalar.end();) {
159 if (*Iter == '-' || *Iter == '{' || *Iter == '}') {
160 ++Iter;
161 continue;
162 }
163 uint8_t Value = (llvm::hexDigitValue(*Iter++) << 4);
164 Value |= llvm::hexDigitValue(*Iter++);
165 *OutBuffer++ = Value;
166 }
167
168 return "";
169}
170
171void ScalarTraits<TypeIndex>::output(const TypeIndex &S, void *,
172 raw_ostream &OS) {
173 OS << S.getIndex();
174}
175
176StringRef ScalarTraits<TypeIndex>::input(StringRef Scalar, void *Ctx,
177 TypeIndex &S) {
178 uint32_t I;
179 StringRef Result = ScalarTraits<uint32_t>::input(Scalar, Ctx, I);
180 S.setIndex(I);
181 return Result;
182}
183
184void ScalarTraits<APSInt>::output(const APSInt &S, void *, raw_ostream &OS) {
185 S.print(OS, S.isSigned());
186}
187
188StringRef ScalarTraits<APSInt>::input(StringRef Scalar, void *Ctx, APSInt &S) {
189 S = APSInt(Scalar);
190 return "";
191}
192
193void ScalarEnumerationTraits<TypeLeafKind>::enumeration(IO &io,
194 TypeLeafKind &Value) {
195#define CV_TYPE(name, val) io.enumCase(Value, #name, name);
196#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
197#undef CV_TYPE
198}
199
200void ScalarEnumerationTraits<PointerToMemberRepresentation>::enumeration(
201 IO &IO, PointerToMemberRepresentation &Value) {
202 IO.enumCase(Value, "Unknown", PointerToMemberRepresentation::Unknown);
203 IO.enumCase(Value, "SingleInheritanceData",
204 PointerToMemberRepresentation::SingleInheritanceData);
205 IO.enumCase(Value, "MultipleInheritanceData",
206 PointerToMemberRepresentation::MultipleInheritanceData);
207 IO.enumCase(Value, "VirtualInheritanceData",
208 PointerToMemberRepresentation::VirtualInheritanceData);
209 IO.enumCase(Value, "GeneralData", PointerToMemberRepresentation::GeneralData);
210 IO.enumCase(Value, "SingleInheritanceFunction",
211 PointerToMemberRepresentation::SingleInheritanceFunction);
212 IO.enumCase(Value, "MultipleInheritanceFunction",
213 PointerToMemberRepresentation::MultipleInheritanceFunction);
214 IO.enumCase(Value, "VirtualInheritanceFunction",
215 PointerToMemberRepresentation::VirtualInheritanceFunction);
216 IO.enumCase(Value, "GeneralFunction",
217 PointerToMemberRepresentation::GeneralFunction);
218}
219
220void ScalarEnumerationTraits<VFTableSlotKind>::enumeration(
221 IO &IO, VFTableSlotKind &Kind) {
222 IO.enumCase(Kind, "Near16", VFTableSlotKind::Near16);
223 IO.enumCase(Kind, "Far16", VFTableSlotKind::Far16);
224 IO.enumCase(Kind, "This", VFTableSlotKind::This);
225 IO.enumCase(Kind, "Outer", VFTableSlotKind::Outer);
226 IO.enumCase(Kind, "Meta", VFTableSlotKind::Meta);
227 IO.enumCase(Kind, "Near", VFTableSlotKind::Near);
228 IO.enumCase(Kind, "Far", VFTableSlotKind::Far);
229}
230
231void ScalarEnumerationTraits<CallingConvention>::enumeration(
232 IO &IO, CallingConvention &Value) {
233 IO.enumCase(Value, "NearC", CallingConvention::NearC);
234 IO.enumCase(Value, "FarC", CallingConvention::FarC);
235 IO.enumCase(Value, "NearPascal", CallingConvention::NearPascal);
236 IO.enumCase(Value, "FarPascal", CallingConvention::FarPascal);
237 IO.enumCase(Value, "NearFast", CallingConvention::NearFast);
238 IO.enumCase(Value, "FarFast", CallingConvention::FarFast);
239 IO.enumCase(Value, "NearStdCall", CallingConvention::NearStdCall);
240 IO.enumCase(Value, "FarStdCall", CallingConvention::FarStdCall);
241 IO.enumCase(Value, "NearSysCall", CallingConvention::NearSysCall);
242 IO.enumCase(Value, "FarSysCall", CallingConvention::FarSysCall);
243 IO.enumCase(Value, "ThisCall", CallingConvention::ThisCall);
244 IO.enumCase(Value, "MipsCall", CallingConvention::MipsCall);
245 IO.enumCase(Value, "Generic", CallingConvention::Generic);
246 IO.enumCase(Value, "AlphaCall", CallingConvention::AlphaCall);
247 IO.enumCase(Value, "PpcCall", CallingConvention::PpcCall);
248 IO.enumCase(Value, "SHCall", CallingConvention::SHCall);
249 IO.enumCase(Value, "ArmCall", CallingConvention::ArmCall);
250 IO.enumCase(Value, "AM33Call", CallingConvention::AM33Call);
251 IO.enumCase(Value, "TriCall", CallingConvention::TriCall);
252 IO.enumCase(Value, "SH5Call", CallingConvention::SH5Call);
253 IO.enumCase(Value, "M32RCall", CallingConvention::M32RCall);
254 IO.enumCase(Value, "ClrCall", CallingConvention::ClrCall);
255 IO.enumCase(Value, "Inline", CallingConvention::Inline);
256 IO.enumCase(Value, "NearVector", CallingConvention::NearVector);
257}
258
259void ScalarEnumerationTraits<PointerKind>::enumeration(IO &IO,
260 PointerKind &Kind) {
261 IO.enumCase(Kind, "Near16", PointerKind::Near16);
262 IO.enumCase(Kind, "Far16", PointerKind::Far16);
263 IO.enumCase(Kind, "Huge16", PointerKind::Huge16);
264 IO.enumCase(Kind, "BasedOnSegment", PointerKind::BasedOnSegment);
265 IO.enumCase(Kind, "BasedOnValue", PointerKind::BasedOnValue);
266 IO.enumCase(Kind, "BasedOnSegmentValue", PointerKind::BasedOnSegmentValue);
267 IO.enumCase(Kind, "BasedOnAddress", PointerKind::BasedOnAddress);
268 IO.enumCase(Kind, "BasedOnSegmentAddress",
269 PointerKind::BasedOnSegmentAddress);
270 IO.enumCase(Kind, "BasedOnType", PointerKind::BasedOnType);
271 IO.enumCase(Kind, "BasedOnSelf", PointerKind::BasedOnSelf);
272 IO.enumCase(Kind, "Near32", PointerKind::Near32);
273 IO.enumCase(Kind, "Far32", PointerKind::Far32);
274 IO.enumCase(Kind, "Near64", PointerKind::Near64);
275}
276
277void ScalarEnumerationTraits<PointerMode>::enumeration(IO &IO,
278 PointerMode &Mode) {
279 IO.enumCase(Mode, "Pointer", PointerMode::Pointer);
280 IO.enumCase(Mode, "LValueReference", PointerMode::LValueReference);
281 IO.enumCase(Mode, "PointerToDataMember", PointerMode::PointerToDataMember);
282 IO.enumCase(Mode, "PointerToMemberFunction",
283 PointerMode::PointerToMemberFunction);
284 IO.enumCase(Mode, "RValueReference", PointerMode::RValueReference);
285}
286
287void ScalarEnumerationTraits<HfaKind>::enumeration(IO &IO, HfaKind &Value) {
288 IO.enumCase(Value, "None", HfaKind::None);
289 IO.enumCase(Value, "Float", HfaKind::Float);
290 IO.enumCase(Value, "Double", HfaKind::Double);
291 IO.enumCase(Value, "Other", HfaKind::Other);
292}
293
294void ScalarEnumerationTraits<MemberAccess>::enumeration(IO &IO,
295 MemberAccess &Access) {
296 IO.enumCase(Access, "None", MemberAccess::None);
297 IO.enumCase(Access, "Private", MemberAccess::Private);
298 IO.enumCase(Access, "Protected", MemberAccess::Protected);
299 IO.enumCase(Access, "Public", MemberAccess::Public);
300}
301
302void ScalarEnumerationTraits<MethodKind>::enumeration(IO &IO,
303 MethodKind &Kind) {
304 IO.enumCase(Kind, "Vanilla", MethodKind::Vanilla);
305 IO.enumCase(Kind, "Virtual", MethodKind::Virtual);
306 IO.enumCase(Kind, "Static", MethodKind::Static);
307 IO.enumCase(Kind, "Friend", MethodKind::Friend);
308 IO.enumCase(Kind, "IntroducingVirtual", MethodKind::IntroducingVirtual);
309 IO.enumCase(Kind, "PureVirtual", MethodKind::PureVirtual);
310 IO.enumCase(Kind, "PureIntroducingVirtual",
311 MethodKind::PureIntroducingVirtual);
312}
313
314void ScalarEnumerationTraits<WindowsRTClassKind>::enumeration(
315 IO &IO, WindowsRTClassKind &Value) {
316 IO.enumCase(Value, "None", WindowsRTClassKind::None);
317 IO.enumCase(Value, "Ref", WindowsRTClassKind::RefClass);
318 IO.enumCase(Value, "Value", WindowsRTClassKind::ValueClass);
319 IO.enumCase(Value, "Interface", WindowsRTClassKind::Interface);
320}
321
322void ScalarEnumerationTraits<LabelType>::enumeration(IO &IO, LabelType &Value) {
323 IO.enumCase(Value, "Near", LabelType::Near);
324 IO.enumCase(Value, "Far", LabelType::Far);
325}
326
327void ScalarBitSetTraits<PointerOptions>::bitset(IO &IO,
328 PointerOptions &Options) {
329 IO.bitSetCase(Options, "None", PointerOptions::None);
330 IO.bitSetCase(Options, "Flat32", PointerOptions::Flat32);
331 IO.bitSetCase(Options, "Volatile", PointerOptions::Volatile);
332 IO.bitSetCase(Options, "Const", PointerOptions::Const);
333 IO.bitSetCase(Options, "Unaligned", PointerOptions::Unaligned);
334 IO.bitSetCase(Options, "Restrict", PointerOptions::Restrict);
335 IO.bitSetCase(Options, "WinRTSmartPointer",
336 PointerOptions::WinRTSmartPointer);
337}
338
339void ScalarBitSetTraits<ModifierOptions>::bitset(IO &IO,
340 ModifierOptions &Options) {
341 IO.bitSetCase(Options, "None", ModifierOptions::None);
342 IO.bitSetCase(Options, "Const", ModifierOptions::Const);
343 IO.bitSetCase(Options, "Volatile", ModifierOptions::Volatile);
344 IO.bitSetCase(Options, "Unaligned", ModifierOptions::Unaligned);
345}
346
347void ScalarBitSetTraits<FunctionOptions>::bitset(IO &IO,
348 FunctionOptions &Options) {
349 IO.bitSetCase(Options, "None", FunctionOptions::None);
350 IO.bitSetCase(Options, "CxxReturnUdt", FunctionOptions::CxxReturnUdt);
351 IO.bitSetCase(Options, "Constructor", FunctionOptions::Constructor);
352 IO.bitSetCase(Options, "ConstructorWithVirtualBases",
353 FunctionOptions::ConstructorWithVirtualBases);
354}
355
356void ScalarBitSetTraits<ClassOptions>::bitset(IO &IO, ClassOptions &Options) {
357 IO.bitSetCase(Options, "None", ClassOptions::None);
358 IO.bitSetCase(Options, "HasConstructorOrDestructor",
359 ClassOptions::HasConstructorOrDestructor);
360 IO.bitSetCase(Options, "HasOverloadedOperator",
361 ClassOptions::HasOverloadedOperator);
362 IO.bitSetCase(Options, "Nested", ClassOptions::Nested);
363 IO.bitSetCase(Options, "ContainsNestedClass",
364 ClassOptions::ContainsNestedClass);
365 IO.bitSetCase(Options, "HasOverloadedAssignmentOperator",
366 ClassOptions::HasOverloadedAssignmentOperator);
367 IO.bitSetCase(Options, "HasConversionOperator",
368 ClassOptions::HasConversionOperator);
369 IO.bitSetCase(Options, "ForwardReference", ClassOptions::ForwardReference);
370 IO.bitSetCase(Options, "Scoped", ClassOptions::Scoped);
371 IO.bitSetCase(Options, "HasUniqueName", ClassOptions::HasUniqueName);
372 IO.bitSetCase(Options, "Sealed", ClassOptions::Sealed);
373 IO.bitSetCase(Options, "Intrinsic", ClassOptions::Intrinsic);
374}
375
376void ScalarBitSetTraits<MethodOptions>::bitset(IO &IO, MethodOptions &Options) {
377 IO.bitSetCase(Options, "None", MethodOptions::None);
378 IO.bitSetCase(Options, "Pseudo", MethodOptions::Pseudo);
379 IO.bitSetCase(Options, "NoInherit", MethodOptions::NoInherit);
380 IO.bitSetCase(Options, "NoConstruct", MethodOptions::NoConstruct);
381 IO.bitSetCase(Options, "CompilerGenerated", MethodOptions::CompilerGenerated);
382 IO.bitSetCase(Options, "Sealed", MethodOptions::Sealed);
383}
384
385void MappingTraits<MemberPointerInfo>::mapping(IO &IO, MemberPointerInfo &MPI) {
386 IO.mapRequired("ContainingType", MPI.ContainingType);
387 IO.mapRequired("Representation", MPI.Representation);
388}
389
390namespace llvm {
391namespace CodeViewYAML {
392namespace detail {
393
394template <> void LeafRecordImpl<ModifierRecord>::map(IO &IO) {
395 IO.mapRequired("ModifiedType", Record.ModifiedType);
396 IO.mapRequired("Modifiers", Record.Modifiers);
397}
398
399template <> void LeafRecordImpl<ProcedureRecord>::map(IO &IO) {
400 IO.mapRequired("ReturnType", Record.ReturnType);
401 IO.mapRequired("CallConv", Record.CallConv);
402 IO.mapRequired("Options", Record.Options);
403 IO.mapRequired("ParameterCount", Record.ParameterCount);
404 IO.mapRequired("ArgumentList", Record.ArgumentList);
405}
406
407template <> void LeafRecordImpl<MemberFunctionRecord>::map(IO &IO) {
408 IO.mapRequired("ReturnType", Record.ReturnType);
409 IO.mapRequired("ClassType", Record.ClassType);
410 IO.mapRequired("ThisType", Record.ThisType);
411 IO.mapRequired("CallConv", Record.CallConv);
412 IO.mapRequired("Options", Record.Options);
413 IO.mapRequired("ParameterCount", Record.ParameterCount);
414 IO.mapRequired("ArgumentList", Record.ArgumentList);
415 IO.mapRequired("ThisPointerAdjustment", Record.ThisPointerAdjustment);
416}
417
418template <> void LeafRecordImpl<LabelRecord>::map(IO &IO) {
419 IO.mapRequired("Mode", Record.Mode);
420}
421
422template <> void LeafRecordImpl<MemberFuncIdRecord>::map(IO &IO) {
423 IO.mapRequired("ClassType", Record.ClassType);
424 IO.mapRequired("FunctionType", Record.FunctionType);
425 IO.mapRequired("Name", Record.Name);
426}
427
428template <> void LeafRecordImpl<ArgListRecord>::map(IO &IO) {
429 IO.mapRequired("ArgIndices", Record.ArgIndices);
430}
431
432template <> void LeafRecordImpl<StringListRecord>::map(IO &IO) {
433 IO.mapRequired("StringIndices", Record.StringIndices);
434}
435
436template <> void LeafRecordImpl<PointerRecord>::map(IO &IO) {
437 IO.mapRequired("ReferentType", Record.ReferentType);
438 IO.mapRequired("Attrs", Record.Attrs);
439 IO.mapOptional("MemberInfo", Record.MemberInfo);
440}
441
442template <> void LeafRecordImpl<ArrayRecord>::map(IO &IO) {
443 IO.mapRequired("ElementType", Record.ElementType);
444 IO.mapRequired("IndexType", Record.IndexType);
445 IO.mapRequired("Size", Record.Size);
446 IO.mapRequired("Name", Record.Name);
447}
448
449void LeafRecordImpl<FieldListRecord>::map(IO &IO) {
450 IO.mapRequired("FieldList", Members);
451}
452
453} // end namespace detail
454} // end namespace CodeViewYAML
455} // end namespace llvm
456
457namespace {
458
459class MemberRecordConversionVisitor : public TypeVisitorCallbacks {
460public:
461 explicit MemberRecordConversionVisitor(std::vector<MemberRecord> &Records)
462 : Records(Records) {}
463
464#define TYPE_RECORD(EnumName, EnumVal, Name)
465#define MEMBER_RECORD(EnumName, EnumVal, Name) \
466 Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
467 return visitKnownMemberImpl(Record); \
468 }
469#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
470#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
471#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
472private:
473 template <typename T> Error visitKnownMemberImpl(T &Record) {
474 TypeLeafKind K = static_cast<TypeLeafKind>(Record.getKind());
475 auto Impl = std::make_shared<MemberRecordImpl<T>>(K);
476 Impl->Record = Record;
477 Records.push_back(MemberRecord{Impl});
478 return Error::success();
479 }
480
481 std::vector<MemberRecord> &Records;
482};
483
484} // end anonymous namespace
485
486Error LeafRecordImpl<FieldListRecord>::fromCodeViewRecord(CVType Type) {
487 MemberRecordConversionVisitor V(Members);
488 return visitMemberRecordStream(Type.content(), V);
489}
490
491CVType
492LeafRecordImpl<FieldListRecord>::toCodeViewRecord(TypeTableBuilder &TTB) const {
493 FieldListRecordBuilder FLRB(TTB);
494 FLRB.begin();
495 for (const auto &Member : Members) {
496 Member.Member->writeTo(FLRB);
497 }
498 FLRB.end(true);
499 return CVType(Kind, TTB.records().back());
500}
501
502void MappingTraits<OneMethodRecord>::mapping(IO &io, OneMethodRecord &Record) {
503 io.mapRequired("Type", Record.Type);
504 io.mapRequired("Attrs", Record.Attrs.Attrs);
505 io.mapRequired("VFTableOffset", Record.VFTableOffset);
506 io.mapRequired("Name", Record.Name);
507}
508
509namespace llvm {
510namespace CodeViewYAML {
511namespace detail {
512
513template <> void LeafRecordImpl<ClassRecord>::map(IO &IO) {
514 IO.mapRequired("MemberCount", Record.MemberCount);
515 IO.mapRequired("Options", Record.Options);
516 IO.mapRequired("FieldList", Record.FieldList);
517 IO.mapRequired("Name", Record.Name);
518 IO.mapRequired("UniqueName", Record.UniqueName);
519 IO.mapRequired("DerivationList", Record.DerivationList);
520 IO.mapRequired("VTableShape", Record.VTableShape);
521 IO.mapRequired("Size", Record.Size);
522}
523
524template <> void LeafRecordImpl<UnionRecord>::map(IO &IO) {
525 IO.mapRequired("MemberCount", Record.MemberCount);
526 IO.mapRequired("Options", Record.Options);
527 IO.mapRequired("FieldList", Record.FieldList);
528 IO.mapRequired("Name", Record.Name);
529 IO.mapRequired("UniqueName", Record.UniqueName);
530 IO.mapRequired("Size", Record.Size);
531}
532
533template <> void LeafRecordImpl<EnumRecord>::map(IO &IO) {
534 IO.mapRequired("NumEnumerators", Record.MemberCount);
535 IO.mapRequired("Options", Record.Options);
536 IO.mapRequired("FieldList", Record.FieldList);
537 IO.mapRequired("Name", Record.Name);
538 IO.mapRequired("UniqueName", Record.UniqueName);
539 IO.mapRequired("UnderlyingType", Record.UnderlyingType);
540}
541
542template <> void LeafRecordImpl<BitFieldRecord>::map(IO &IO) {
543 IO.mapRequired("Type", Record.Type);
544 IO.mapRequired("BitSize", Record.BitSize);
545 IO.mapRequired("BitOffset", Record.BitOffset);
546}
547
548template <> void LeafRecordImpl<VFTableShapeRecord>::map(IO &IO) {
549 IO.mapRequired("Slots", Record.Slots);
550}
551
552template <> void LeafRecordImpl<TypeServer2Record>::map(IO &IO) {
553 IO.mapRequired("Guid", Record.Guid);
554 IO.mapRequired("Age", Record.Age);
555 IO.mapRequired("Name", Record.Name);
556}
557
558template <> void LeafRecordImpl<StringIdRecord>::map(IO &IO) {
559 IO.mapRequired("Id", Record.Id);
560 IO.mapRequired("String", Record.String);
561}
562
563template <> void LeafRecordImpl<FuncIdRecord>::map(IO &IO) {
564 IO.mapRequired("ParentScope", Record.ParentScope);
565 IO.mapRequired("FunctionType", Record.FunctionType);
566 IO.mapRequired("Name", Record.Name);
567}
568
569template <> void LeafRecordImpl<UdtSourceLineRecord>::map(IO &IO) {
570 IO.mapRequired("UDT", Record.UDT);
571 IO.mapRequired("SourceFile", Record.SourceFile);
572 IO.mapRequired("LineNumber", Record.LineNumber);
573}
574
575template <> void LeafRecordImpl<UdtModSourceLineRecord>::map(IO &IO) {
576 IO.mapRequired("UDT", Record.UDT);
577 IO.mapRequired("SourceFile", Record.SourceFile);
578 IO.mapRequired("LineNumber", Record.LineNumber);
579 IO.mapRequired("Module", Record.Module);
580}
581
582template <> void LeafRecordImpl<BuildInfoRecord>::map(IO &IO) {
583 IO.mapRequired("ArgIndices", Record.ArgIndices);
584}
585
586template <> void LeafRecordImpl<VFTableRecord>::map(IO &IO) {
587 IO.mapRequired("CompleteClass", Record.CompleteClass);
588 IO.mapRequired("OverriddenVFTable", Record.OverriddenVFTable);
589 IO.mapRequired("VFPtrOffset", Record.VFPtrOffset);
590 IO.mapRequired("MethodNames", Record.MethodNames);
591}
592
593template <> void LeafRecordImpl<MethodOverloadListRecord>::map(IO &IO) {
594 IO.mapRequired("Methods", Record.Methods);
595}
596
597template <> void MemberRecordImpl<OneMethodRecord>::map(IO &IO) {
598 MappingTraits<OneMethodRecord>::mapping(IO, Record);
599}
600
601template <> void MemberRecordImpl<OverloadedMethodRecord>::map(IO &IO) {
602 IO.mapRequired("NumOverloads", Record.NumOverloads);
603 IO.mapRequired("MethodList", Record.MethodList);
604 IO.mapRequired("Name", Record.Name);
605}
606
607template <> void MemberRecordImpl<NestedTypeRecord>::map(IO &IO) {
608 IO.mapRequired("Type", Record.Type);
609 IO.mapRequired("Name", Record.Name);
610}
611
612template <> void MemberRecordImpl<DataMemberRecord>::map(IO &IO) {
613 IO.mapRequired("Attrs", Record.Attrs.Attrs);
614 IO.mapRequired("Type", Record.Type);
615 IO.mapRequired("FieldOffset", Record.FieldOffset);
616 IO.mapRequired("Name", Record.Name);
617}
618
619template <> void MemberRecordImpl<StaticDataMemberRecord>::map(IO &IO) {
620 IO.mapRequired("Attrs", Record.Attrs.Attrs);
621 IO.mapRequired("Type", Record.Type);
622 IO.mapRequired("Name", Record.Name);
623}
624
625template <> void MemberRecordImpl<EnumeratorRecord>::map(IO &IO) {
626 IO.mapRequired("Attrs", Record.Attrs.Attrs);
627 IO.mapRequired("Value", Record.Value);
628 IO.mapRequired("Name", Record.Name);
629}
630
631template <> void MemberRecordImpl<VFPtrRecord>::map(IO &IO) {
632 IO.mapRequired("Type", Record.Type);
633}
634
635template <> void MemberRecordImpl<BaseClassRecord>::map(IO &IO) {
636 IO.mapRequired("Attrs", Record.Attrs.Attrs);
637 IO.mapRequired("Type", Record.Type);
638 IO.mapRequired("Offset", Record.Offset);
639}
640
641template <> void MemberRecordImpl<VirtualBaseClassRecord>::map(IO &IO) {
642 IO.mapRequired("Attrs", Record.Attrs.Attrs);
643 IO.mapRequired("BaseType", Record.BaseType);
644 IO.mapRequired("VBPtrType", Record.VBPtrType);
645 IO.mapRequired("VBPtrOffset", Record.VBPtrOffset);
646 IO.mapRequired("VTableIndex", Record.VTableIndex);
647}
648
649template <> void MemberRecordImpl<ListContinuationRecord>::map(IO &IO) {
650 IO.mapRequired("ContinuationIndex", Record.ContinuationIndex);
651}
652
653} // end namespace detail
654} // end namespace CodeViewYAML
655} // end namespace llvm
656
657template <typename T>
658static inline Expected<LeafRecord> fromCodeViewRecordImpl(CVType Type) {
659 LeafRecord Result;
660
661 auto Impl = std::make_shared<LeafRecordImpl<T>>(Type.kind());
662 if (auto EC = Impl->fromCodeViewRecord(Type))
663 return std::move(EC);
664 Result.Leaf = Impl;
665 return Result;
666}
667
668Expected<LeafRecord> LeafRecord::fromCodeViewRecord(CVType Type) {
669#define TYPE_RECORD(EnumName, EnumVal, ClassName) \
670 case EnumName: \
671 return fromCodeViewRecordImpl<ClassName##Record>(Type);
672#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
673 TYPE_RECORD(EnumName, EnumVal, ClassName)
674#define MEMBER_RECORD(EnumName, EnumVal, ClassName)
675#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)
676 switch (Type.kind()) {
677#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
678 default:
679 llvm_unreachable("Unknown leaf kind!")::llvm::llvm_unreachable_internal("Unknown leaf kind!", "/build/llvm-toolchain-snapshot-6.0~svn318601/lib/ObjectYAML/CodeViewYAMLTypes.cpp"
, 679)
;
680 }
681 return make_error<CodeViewError>(cv_error_code::corrupt_record);
682}
683
684CVType LeafRecord::toCodeViewRecord(BumpPtrAllocator &Alloc) const {
685 TypeTableBuilder TTB(Alloc);
686 return Leaf->toCodeViewRecord(TTB);
687}
688
689CVType LeafRecord::toCodeViewRecord(TypeTableBuilder &TTB) const {
690 return Leaf->toCodeViewRecord(TTB);
691}
692
693namespace llvm {
694namespace yaml {
695
696template <> struct MappingTraits<LeafRecordBase> {
697 static void mapping(IO &io, LeafRecordBase &Record) { Record.map(io); }
698};
699
700template <> struct MappingTraits<MemberRecordBase> {
701 static void mapping(IO &io, MemberRecordBase &Record) { Record.map(io); }
702};
703
704} // end namespace yaml
705} // end namespace llvm
706
707template <typename ConcreteType>
708static void mapLeafRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind,
709 LeafRecord &Obj) {
710 if (!IO.outputting())
711 Obj.Leaf = std::make_shared<LeafRecordImpl<ConcreteType>>(Kind);
712
713 if (Kind == LF_FIELDLIST)
714 Obj.Leaf->map(IO);
715 else
716 IO.mapRequired(Class, *Obj.Leaf);
717}
718
719void MappingTraits<LeafRecord>::mapping(IO &IO, LeafRecord &Obj) {
720 TypeLeafKind Kind;
1
'Kind' declared without an initial value
721 if (IO.outputting())
2
Assuming the condition is false
3
Taking false branch
722 Kind = Obj.Leaf->Kind;
723 IO.mapRequired("Kind", Kind);
4
Calling 'IO::mapRequired'
724
725#define TYPE_RECORD(EnumName, EnumVal, ClassName) \
726 case EnumName: \
727 mapLeafRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \
728 break;
729#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
730 TYPE_RECORD(EnumName, EnumVal, ClassName)
731#define MEMBER_RECORD(EnumName, EnumVal, ClassName)
732#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)
733 switch (Kind) {
734#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
735 default: { llvm_unreachable("Unknown leaf kind!")::llvm::llvm_unreachable_internal("Unknown leaf kind!", "/build/llvm-toolchain-snapshot-6.0~svn318601/lib/ObjectYAML/CodeViewYAMLTypes.cpp"
, 735)
; }
736 }
737}
738
739template <typename ConcreteType>
740static void mapMemberRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind,
741 MemberRecord &Obj) {
742 if (!IO.outputting())
743 Obj.Member = std::make_shared<MemberRecordImpl<ConcreteType>>(Kind);
744
745 IO.mapRequired(Class, *Obj.Member);
746}
747
748void MappingTraits<MemberRecord>::mapping(IO &IO, MemberRecord &Obj) {
749 TypeLeafKind Kind;
750 if (IO.outputting())
751 Kind = Obj.Member->Kind;
752 IO.mapRequired("Kind", Kind);
753
754#define MEMBER_RECORD(EnumName, EnumVal, ClassName) \
755 case EnumName: \
756 mapMemberRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \
757 break;
758#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
759 MEMBER_RECORD(EnumName, EnumVal, ClassName)
760#define TYPE_RECORD(EnumName, EnumVal, ClassName)
761#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)
762 switch (Kind) {
763#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
764 default: { llvm_unreachable("Unknown member kind!")::llvm::llvm_unreachable_internal("Unknown member kind!", "/build/llvm-toolchain-snapshot-6.0~svn318601/lib/ObjectYAML/CodeViewYAMLTypes.cpp"
, 764)
; }
765 }
766}
767
768std::vector<LeafRecord>
769llvm::CodeViewYAML::fromDebugT(ArrayRef<uint8_t> DebugT) {
770 ExitOnError Err("Invalid .debug$T section!");
771 BinaryStreamReader Reader(DebugT, support::little);
772 CVTypeArray Types;
773 uint32_t Magic;
774
775 Err(Reader.readInteger(Magic));
776 assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$T section!")(static_cast <bool> (Magic == COFF::DEBUG_SECTION_MAGIC
&& "Invalid .debug$T section!") ? void (0) : __assert_fail
("Magic == COFF::DEBUG_SECTION_MAGIC && \"Invalid .debug$T section!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/lib/ObjectYAML/CodeViewYAMLTypes.cpp"
, 776, __extension__ __PRETTY_FUNCTION__))
;
777
778 std::vector<LeafRecord> Result;
779 Err(Reader.readArray(Types, Reader.bytesRemaining()));
780 for (const auto &T : Types) {
781 auto CVT = Err(LeafRecord::fromCodeViewRecord(T));
782 Result.push_back(CVT);
783 }
784 return Result;
785}
786
787ArrayRef<uint8_t> llvm::CodeViewYAML::toDebugT(ArrayRef<LeafRecord> Leafs,
788 BumpPtrAllocator &Alloc) {
789 TypeTableBuilder TTB(Alloc, false);
790 uint32_t Size = sizeof(uint32_t);
791 for (const auto &Leaf : Leafs) {
792 CVType T = Leaf.toCodeViewRecord(TTB);
793 Size += T.length();
794 assert(T.length() % 4 == 0 && "Improper type record alignment!")(static_cast <bool> (T.length() % 4 == 0 && "Improper type record alignment!"
) ? void (0) : __assert_fail ("T.length() % 4 == 0 && \"Improper type record alignment!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/lib/ObjectYAML/CodeViewYAMLTypes.cpp"
, 794, __extension__ __PRETTY_FUNCTION__))
;
795 }
796 uint8_t *ResultBuffer = Alloc.Allocate<uint8_t>(Size);
797 MutableArrayRef<uint8_t> Output(ResultBuffer, Size);
798 BinaryStreamWriter Writer(Output, support::little);
799 ExitOnError Err("Error writing type record to .debug$T section");
800 Err(Writer.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC));
801 for (const auto &R : TTB.records()) {
802 Err(Writer.writeBytes(R));
803 }
804 assert(Writer.bytesRemaining() == 0 && "Didn't write all type record bytes!")(static_cast <bool> (Writer.bytesRemaining() == 0 &&
"Didn't write all type record bytes!") ? void (0) : __assert_fail
("Writer.bytesRemaining() == 0 && \"Didn't write all type record bytes!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/lib/ObjectYAML/CodeViewYAMLTypes.cpp"
, 804, __extension__ __PRETTY_FUNCTION__))
;
805 return Output;
806}

/build/llvm-toolchain-snapshot-6.0~svn318601/include/llvm/Support/YAMLTraits.h

1//===- llvm/Support/YAMLTraits.h --------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_SUPPORT_YAMLTRAITS_H
11#define LLVM_SUPPORT_YAMLTRAITS_H
12
13#include "llvm/ADT/Optional.h"
14#include "llvm/ADT/SmallVector.h"
15#include "llvm/ADT/StringMap.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/ADT/Twine.h"
18#include "llvm/Support/AlignOf.h"
19#include "llvm/Support/Allocator.h"
20#include "llvm/Support/Endian.h"
21#include "llvm/Support/Regex.h"
22#include "llvm/Support/SourceMgr.h"
23#include "llvm/Support/YAMLParser.h"
24#include "llvm/Support/raw_ostream.h"
25#include <cassert>
26#include <cctype>
27#include <cstddef>
28#include <cstdint>
29#include <map>
30#include <memory>
31#include <new>
32#include <string>
33#include <system_error>
34#include <type_traits>
35#include <vector>
36
37namespace llvm {
38namespace yaml {
39
40struct EmptyContext {};
41
42/// This class should be specialized by any type that needs to be converted
43/// to/from a YAML mapping. For example:
44///
45/// struct MappingTraits<MyStruct> {
46/// static void mapping(IO &io, MyStruct &s) {
47/// io.mapRequired("name", s.name);
48/// io.mapRequired("size", s.size);
49/// io.mapOptional("age", s.age);
50/// }
51/// };
52template<class T>
53struct MappingTraits {
54 // Must provide:
55 // static void mapping(IO &io, T &fields);
56 // Optionally may provide:
57 // static StringRef validate(IO &io, T &fields);
58 //
59 // The optional flow flag will cause generated YAML to use a flow mapping
60 // (e.g. { a: 0, b: 1 }):
61 // static const bool flow = true;
62};
63
64/// This class is similar to MappingTraits<T> but allows you to pass in
65/// additional context for each map operation. For example:
66///
67/// struct MappingContextTraits<MyStruct, MyContext> {
68/// static void mapping(IO &io, MyStruct &s, MyContext &c) {
69/// io.mapRequired("name", s.name);
70/// io.mapRequired("size", s.size);
71/// io.mapOptional("age", s.age);
72/// ++c.TimesMapped;
73/// }
74/// };
75template <class T, class Context> struct MappingContextTraits {
76 // Must provide:
77 // static void mapping(IO &io, T &fields, Context &Ctx);
78 // Optionally may provide:
79 // static StringRef validate(IO &io, T &fields, Context &Ctx);
80 //
81 // The optional flow flag will cause generated YAML to use a flow mapping
82 // (e.g. { a: 0, b: 1 }):
83 // static const bool flow = true;
84};
85
86/// This class should be specialized by any integral type that converts
87/// to/from a YAML scalar where there is a one-to-one mapping between
88/// in-memory values and a string in YAML. For example:
89///
90/// struct ScalarEnumerationTraits<Colors> {
91/// static void enumeration(IO &io, Colors &value) {
92/// io.enumCase(value, "red", cRed);
93/// io.enumCase(value, "blue", cBlue);
94/// io.enumCase(value, "green", cGreen);
95/// }
96/// };
97template<typename T>
98struct ScalarEnumerationTraits {
99 // Must provide:
100 // static void enumeration(IO &io, T &value);
101};
102
103/// This class should be specialized by any integer type that is a union
104/// of bit values and the YAML representation is a flow sequence of
105/// strings. For example:
106///
107/// struct ScalarBitSetTraits<MyFlags> {
108/// static void bitset(IO &io, MyFlags &value) {
109/// io.bitSetCase(value, "big", flagBig);
110/// io.bitSetCase(value, "flat", flagFlat);
111/// io.bitSetCase(value, "round", flagRound);
112/// }
113/// };
114template<typename T>
115struct ScalarBitSetTraits {
116 // Must provide:
117 // static void bitset(IO &io, T &value);
118};
119
120/// This class should be specialized by type that requires custom conversion
121/// to/from a yaml scalar. For example:
122///
123/// template<>
124/// struct ScalarTraits<MyType> {
125/// static void output(const MyType &val, void*, llvm::raw_ostream &out) {
126/// // stream out custom formatting
127/// out << llvm::format("%x", val);
128/// }
129/// static StringRef input(StringRef scalar, void*, MyType &value) {
130/// // parse scalar and set `value`
131/// // return empty string on success, or error string
132/// return StringRef();
133/// }
134/// static bool mustQuote(StringRef) { return true; }
135/// };
136template<typename T>
137struct ScalarTraits {
138 // Must provide:
139 //
140 // Function to write the value as a string:
141 //static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
142 //
143 // Function to convert a string to a value. Returns the empty
144 // StringRef on success or an error string if string is malformed:
145 //static StringRef input(StringRef scalar, void *ctxt, T &value);
146 //
147 // Function to determine if the value should be quoted.
148 //static bool mustQuote(StringRef);
149};
150
151/// This class should be specialized by type that requires custom conversion
152/// to/from a YAML literal block scalar. For example:
153///
154/// template <>
155/// struct BlockScalarTraits<MyType> {
156/// static void output(const MyType &Value, void*, llvm::raw_ostream &Out)
157/// {
158/// // stream out custom formatting
159/// Out << Val;
160/// }
161/// static StringRef input(StringRef Scalar, void*, MyType &Value) {
162/// // parse scalar and set `value`
163/// // return empty string on success, or error string
164/// return StringRef();
165/// }
166/// };
167template <typename T>
168struct BlockScalarTraits {
169 // Must provide:
170 //
171 // Function to write the value as a string:
172 // static void output(const T &Value, void *ctx, llvm::raw_ostream &Out);
173 //
174 // Function to convert a string to a value. Returns the empty
175 // StringRef on success or an error string if string is malformed:
176 // static StringRef input(StringRef Scalar, void *ctxt, T &Value);
177};
178
179/// This class should be specialized by any type that needs to be converted
180/// to/from a YAML sequence. For example:
181///
182/// template<>
183/// struct SequenceTraits<MyContainer> {
184/// static size_t size(IO &io, MyContainer &seq) {
185/// return seq.size();
186/// }
187/// static MyType& element(IO &, MyContainer &seq, size_t index) {
188/// if ( index >= seq.size() )
189/// seq.resize(index+1);
190/// return seq[index];
191/// }
192/// };
193template<typename T, typename EnableIf = void>
194struct SequenceTraits {
195 // Must provide:
196 // static size_t size(IO &io, T &seq);
197 // static T::value_type& element(IO &io, T &seq, size_t index);
198 //
199 // The following is option and will cause generated YAML to use
200 // a flow sequence (e.g. [a,b,c]).
201 // static const bool flow = true;
202};
203
204/// This class should be specialized by any type for which vectors of that
205/// type need to be converted to/from a YAML sequence.
206template<typename T, typename EnableIf = void>
207struct SequenceElementTraits {
208 // Must provide:
209 // static const bool flow;
210};
211
212/// This class should be specialized by any type that needs to be converted
213/// to/from a list of YAML documents.
214template<typename T>
215struct DocumentListTraits {
216 // Must provide:
217 // static size_t size(IO &io, T &seq);
218 // static T::value_type& element(IO &io, T &seq, size_t index);
219};
220
221/// This class should be specialized by any type that needs to be converted
222/// to/from a YAML mapping in the case where the names of the keys are not known
223/// in advance, e.g. a string map.
224template <typename T>
225struct CustomMappingTraits {
226 // static void inputOne(IO &io, StringRef key, T &elem);
227 // static void output(IO &io, T &elem);
228};
229
230// Only used for better diagnostics of missing traits
231template <typename T>
232struct MissingTrait;
233
234// Test if ScalarEnumerationTraits<T> is defined on type T.
235template <class T>
236struct has_ScalarEnumerationTraits
237{
238 using Signature_enumeration = void (*)(class IO&, T&);
239
240 template <typename U>
241 static char test(SameType<Signature_enumeration, &U::enumeration>*);
242
243 template <typename U>
244 static double test(...);
245
246public:
247 static bool const value =
248 (sizeof(test<ScalarEnumerationTraits<T>>(nullptr)) == 1);
249};
250
251// Test if ScalarBitSetTraits<T> is defined on type T.
252template <class T>
253struct has_ScalarBitSetTraits
254{
255 using Signature_bitset = void (*)(class IO&, T&);
256
257 template <typename U>
258 static char test(SameType<Signature_bitset, &U::bitset>*);
259
260 template <typename U>
261 static double test(...);
262
263public:
264 static bool const value = (sizeof(test<ScalarBitSetTraits<T>>(nullptr)) == 1);
265};
266
267// Test if ScalarTraits<T> is defined on type T.
268template <class T>
269struct has_ScalarTraits
270{
271 using Signature_input = StringRef (*)(StringRef, void*, T&);
272 using Signature_output = void (*)(const T&, void*, raw_ostream&);
273 using Signature_mustQuote = bool (*)(StringRef);
274
275 template <typename U>
276 static char test(SameType<Signature_input, &U::input> *,
277 SameType<Signature_output, &U::output> *,
278 SameType<Signature_mustQuote, &U::mustQuote> *);
279
280 template <typename U>
281 static double test(...);
282
283public:
284 static bool const value =
285 (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
286};
287
288// Test if BlockScalarTraits<T> is defined on type T.
289template <class T>
290struct has_BlockScalarTraits
291{
292 using Signature_input = StringRef (*)(StringRef, void *, T &);
293 using Signature_output = void (*)(const T &, void *, raw_ostream &);
294
295 template <typename U>
296 static char test(SameType<Signature_input, &U::input> *,
297 SameType<Signature_output, &U::output> *);
298
299 template <typename U>
300 static double test(...);
301
302public:
303 static bool const value =
304 (sizeof(test<BlockScalarTraits<T>>(nullptr, nullptr)) == 1);
305};
306
307// Test if MappingContextTraits<T> is defined on type T.
308template <class T, class Context> struct has_MappingTraits {
309 using Signature_mapping = void (*)(class IO &, T &, Context &);
310
311 template <typename U>
312 static char test(SameType<Signature_mapping, &U::mapping>*);
313
314 template <typename U>
315 static double test(...);
316
317public:
318 static bool const value =
319 (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
320};
321
322// Test if MappingTraits<T> is defined on type T.
323template <class T> struct has_MappingTraits<T, EmptyContext> {
324 using Signature_mapping = void (*)(class IO &, T &);
325
326 template <typename U>
327 static char test(SameType<Signature_mapping, &U::mapping> *);
328
329 template <typename U> static double test(...);
330
331public:
332 static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
333};
334
335// Test if MappingContextTraits<T>::validate() is defined on type T.
336template <class T, class Context> struct has_MappingValidateTraits {
337 using Signature_validate = StringRef (*)(class IO &, T &, Context &);
338
339 template <typename U>
340 static char test(SameType<Signature_validate, &U::validate>*);
341
342 template <typename U>
343 static double test(...);
344
345public:
346 static bool const value =
347 (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
348};
349
350// Test if MappingTraits<T>::validate() is defined on type T.
351template <class T> struct has_MappingValidateTraits<T, EmptyContext> {
352 using Signature_validate = StringRef (*)(class IO &, T &);
353
354 template <typename U>
355 static char test(SameType<Signature_validate, &U::validate> *);
356
357 template <typename U> static double test(...);
358
359public:
360 static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
361};
362
363// Test if SequenceTraits<T> is defined on type T.
364template <class T>
365struct has_SequenceMethodTraits
366{
367 using Signature_size = size_t (*)(class IO&, T&);
368
369 template <typename U>
370 static char test(SameType<Signature_size, &U::size>*);
371
372 template <typename U>
373 static double test(...);
374
375public:
376 static bool const value = (sizeof(test<SequenceTraits<T>>(nullptr)) == 1);
377};
378
379// Test if CustomMappingTraits<T> is defined on type T.
380template <class T>
381struct has_CustomMappingTraits
382{
383 using Signature_input = void (*)(IO &io, StringRef key, T &v);
384
385 template <typename U>
386 static char test(SameType<Signature_input, &U::inputOne>*);
387
388 template <typename U>
389 static double test(...);
390
391public:
392 static bool const value =
393 (sizeof(test<CustomMappingTraits<T>>(nullptr)) == 1);
394};
395
396// has_FlowTraits<int> will cause an error with some compilers because
397// it subclasses int. Using this wrapper only instantiates the
398// real has_FlowTraits only if the template type is a class.
399template <typename T, bool Enabled = std::is_class<T>::value>
400class has_FlowTraits
401{
402public:
403 static const bool value = false;
404};
405
406// Some older gcc compilers don't support straight forward tests
407// for members, so test for ambiguity cause by the base and derived
408// classes both defining the member.
409template <class T>
410struct has_FlowTraits<T, true>
411{
412 struct Fallback { bool flow; };
413 struct Derived : T, Fallback { };
414
415 template<typename C>
416 static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
417
418 template<typename C>
419 static char (&f(...))[2];
420
421public:
422 static bool const value = sizeof(f<Derived>(nullptr)) == 2;
423};
424
425// Test if SequenceTraits<T> is defined on type T
426template<typename T>
427struct has_SequenceTraits : public std::integral_constant<bool,
428 has_SequenceMethodTraits<T>::value > { };
429
430// Test if DocumentListTraits<T> is defined on type T
431template <class T>
432struct has_DocumentListTraits
433{
434 using Signature_size = size_t (*)(class IO &, T &);
435
436 template <typename U>
437 static char test(SameType<Signature_size, &U::size>*);
438
439 template <typename U>
440 static double test(...);
441
442public:
443 static bool const value = (sizeof(test<DocumentListTraits<T>>(nullptr))==1);
444};
445
446inline bool isNumber(StringRef S) {
447 static const char OctalChars[] = "01234567";
448 if (S.startswith("0") &&
449 S.drop_front().find_first_not_of(OctalChars) == StringRef::npos)
450 return true;
451
452 if (S.startswith("0o") &&
453 S.drop_front(2).find_first_not_of(OctalChars) == StringRef::npos)
454 return true;
455
456 static const char HexChars[] = "0123456789abcdefABCDEF";
457 if (S.startswith("0x") &&
458 S.drop_front(2).find_first_not_of(HexChars) == StringRef::npos)
459 return true;
460
461 static const char DecChars[] = "0123456789";
462 if (S.find_first_not_of(DecChars) == StringRef::npos)
463 return true;
464
465 if (S.equals(".inf") || S.equals(".Inf") || S.equals(".INF"))
466 return true;
467
468 Regex FloatMatcher("^(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?$");
469 if (FloatMatcher.match(S))
470 return true;
471
472 return false;
473}
474
475inline bool isNumeric(StringRef S) {
476 if ((S.front() == '-' || S.front() == '+') && isNumber(S.drop_front()))
477 return true;
478
479 if (isNumber(S))
480 return true;
481
482 if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
483 return true;
484
485 return false;
486}
487
488inline bool isNull(StringRef S) {
489 return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
490 S.equals("~");
491}
492
493inline bool isBool(StringRef S) {
494 return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
495 S.equals("false") || S.equals("False") || S.equals("FALSE");
496}
497
498inline bool needsQuotes(StringRef S) {
499 if (S.empty())
500 return true;
501 if (isspace(S.front()) || isspace(S.back()))
502 return true;
503 if (S.front() == ',')
504 return true;
505
506 static const char ScalarSafeChars[] =
507 "abcdefghijklmnopqrstuvwxyz"
508 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
509 if (S.find_first_not_of(ScalarSafeChars) != StringRef::npos)
510 return true;
511
512 if (isNull(S))
513 return true;
514 if (isBool(S))
515 return true;
516 if (isNumeric(S))
517 return true;
518
519 return false;
520}
521
522template <typename T, typename Context>
523struct missingTraits
524 : public std::integral_constant<bool,
525 !has_ScalarEnumerationTraits<T>::value &&
526 !has_ScalarBitSetTraits<T>::value &&
527 !has_ScalarTraits<T>::value &&
528 !has_BlockScalarTraits<T>::value &&
529 !has_MappingTraits<T, Context>::value &&
530 !has_SequenceTraits<T>::value &&
531 !has_CustomMappingTraits<T>::value &&
532 !has_DocumentListTraits<T>::value> {};
533
534template <typename T, typename Context>
535struct validatedMappingTraits
536 : public std::integral_constant<
537 bool, has_MappingTraits<T, Context>::value &&
538 has_MappingValidateTraits<T, Context>::value> {};
539
540template <typename T, typename Context>
541struct unvalidatedMappingTraits
542 : public std::integral_constant<
543 bool, has_MappingTraits<T, Context>::value &&
544 !has_MappingValidateTraits<T, Context>::value> {};
545
546// Base class for Input and Output.
547class IO {
548public:
549 IO(void *Ctxt = nullptr);
550 virtual ~IO();
551
552 virtual bool outputting() = 0;
553
554 virtual unsigned beginSequence() = 0;
555 virtual bool preflightElement(unsigned, void *&) = 0;
556 virtual void postflightElement(void*) = 0;
557 virtual void endSequence() = 0;
558 virtual bool canElideEmptySequence() = 0;
559
560 virtual unsigned beginFlowSequence() = 0;
561 virtual bool preflightFlowElement(unsigned, void *&) = 0;
562 virtual void postflightFlowElement(void*) = 0;
563 virtual void endFlowSequence() = 0;
564
565 virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
566 virtual void beginMapping() = 0;
567 virtual void endMapping() = 0;
568 virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
569 virtual void postflightKey(void*) = 0;
570 virtual std::vector<StringRef> keys() = 0;
571
572 virtual void beginFlowMapping() = 0;
573 virtual void endFlowMapping() = 0;
574
575 virtual void beginEnumScalar() = 0;
576 virtual bool matchEnumScalar(const char*, bool) = 0;
577 virtual bool matchEnumFallback() = 0;
578 virtual void endEnumScalar() = 0;
579
580 virtual bool beginBitSetScalar(bool &) = 0;
581 virtual bool bitSetMatch(const char*, bool) = 0;
582 virtual void endBitSetScalar() = 0;
583
584 virtual void scalarString(StringRef &, bool) = 0;
585 virtual void blockScalarString(StringRef &) = 0;
586
587 virtual void setError(const Twine &) = 0;
588
589 template <typename T>
590 void enumCase(T &Val, const char* Str, const T ConstVal) {
591 if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
13
Assuming the condition is false
14
Assuming the condition is false
15
Taking false branch
17
Assuming the condition is false
18
Assuming the condition is false
19
Taking false branch
21
Assuming the condition is false
22
Assuming the condition is false
23
Taking false branch
25
Assuming the condition is false
26
Assuming the condition is false
27
Taking false branch
29
Assuming the condition is false
30
Assuming the condition is false
31
Taking false branch
33
Assuming the condition is false
34
Assuming the condition is false
35
Taking false branch
37
Assuming the condition is false
38
Assuming the condition is false
39
Taking false branch
41
Assuming the condition is false
42
Assuming the condition is false
43
Taking false branch
45
Assuming the condition is false
46
Assuming the condition is false
47
Taking false branch
49
Assuming the condition is false
50
Assuming the condition is false
51
Taking false branch
53
Assuming the condition is false
54
Assuming the condition is false
55
Taking false branch
57
Assuming the condition is false
58
Assuming the condition is false
59
Taking false branch
61
Assuming the condition is false
62
Assuming the condition is false
63
Taking false branch
65
Assuming the condition is false
66
Assuming the condition is false
67
Taking false branch
69
Assuming the condition is false
70
Assuming the condition is false
71
Taking false branch
73
Assuming the condition is false
74
Assuming the condition is false
75
Taking false branch
77
Assuming the condition is false
78
Assuming the condition is false
79
Taking false branch
81
Assuming the condition is false
82
Assuming the condition is false
83
Taking false branch
85
Assuming the condition is false
86
Assuming the condition is false
87
Taking false branch
89
Assuming the condition is false
90
Assuming the condition is false
91
Taking false branch
93
Assuming the condition is false
94
Assuming the condition is false
95
Taking false branch
97
Assuming the condition is false
98
Assuming the condition is false
99
Taking false branch
101
Assuming the condition is false
102
Assuming the condition is false
103
Taking false branch
105
Assuming the condition is false
106
Assuming the condition is false
107
Taking false branch
109
Assuming the condition is false
110
Assuming the condition is false
111
Taking false branch
113
Assuming the condition is false
114
Assuming the condition is false
115
Taking false branch
117
Assuming the condition is false
118
Assuming the condition is false
119
Taking false branch
121
Assuming the condition is false
122
Assuming the condition is false
123
Taking false branch
125
Assuming the condition is false
126
Assuming the condition is false
127
Taking false branch
129
Assuming the condition is false
130
Assuming the condition is false
131
Taking false branch
133
Assuming the condition is false
134
Assuming the condition is false
135
Taking false branch
137
Assuming the condition is false
138
Assuming the condition is false
139
Taking false branch
141
Assuming the condition is false
142
Assuming the condition is false
143
Taking false branch
145
Assuming the condition is false
146
Assuming the condition is false
147
Taking false branch
149
Assuming the condition is false
150
Assuming the condition is false
151
Taking false branch
153
Assuming the condition is false
154
Assuming the condition is false
155
Taking false branch
157
Assuming the condition is false
158
Assuming the condition is false
159
Taking false branch
161
Assuming the condition is false
162
Assuming the condition is false
163
Taking false branch
165
Assuming the condition is false
166
Assuming the condition is false
167
Taking false branch
169
Assuming the condition is false
170
Assuming the condition is false
171
Taking false branch
173
Assuming the condition is false
174
Assuming the condition is false
175
Taking false branch
177
Assuming the condition is false
178
Assuming the condition is false
179
Taking false branch
181
Assuming the condition is false
182
Assuming the condition is false
183
Taking false branch
185
Assuming the condition is false
186
Assuming the condition is false
187
Taking false branch
189
Assuming the condition is false
190
Assuming the condition is false
191
Taking false branch
193
Assuming the condition is false
194
Assuming the condition is false
195
Taking false branch
197
Assuming the condition is false
198
Assuming the condition is false
199
Taking false branch
201
Assuming the condition is false
202
Assuming the condition is false
203
Taking false branch
205
Assuming the condition is false
206
Assuming the condition is false
207
Taking false branch
209
Assuming the condition is false
210
Assuming the condition is false
211
Taking false branch
213
Assuming the condition is false
214
Assuming the condition is false
215
Taking false branch
217
Assuming the condition is false
218
Assuming the condition is false
219
Taking false branch
221
Assuming the condition is false
222
Assuming the condition is false
223
Taking false branch
225
Assuming the condition is false
226
Assuming the condition is false
227
Taking false branch
229
Assuming the condition is false
230
Assuming the condition is false
231
Taking false branch
233
Assuming the condition is false
234
Assuming the condition is false
235
Taking false branch
237
Assuming the condition is false
238
Assuming the condition is false
239
Taking false branch
241
Assuming the condition is false
242
Assuming the condition is false
243
Taking false branch
245
Assuming the condition is false
246
Assuming the condition is false
247
Taking false branch
249
Assuming the condition is false
250
Assuming the condition is false
251
Taking false branch
253
Assuming the condition is false
254
Assuming the condition is false
255
Taking false branch
257
Assuming the condition is false
258
Assuming the condition is false
259
Taking false branch
261
Assuming the condition is false
262
Assuming the condition is false
263
Taking false branch
265
Assuming the condition is false
266
Assuming the condition is false
267
Taking false branch
269
Assuming the condition is false
270
Assuming the condition is false
271
Taking false branch
273
Assuming the condition is false
274
Assuming the condition is false
275
Taking false branch
277
Assuming the condition is false
278
Assuming the condition is false
279
Taking false branch
281
Assuming the condition is false
282
Assuming the condition is false
283
Taking false branch
285
Assuming the condition is false
286
Assuming the condition is false
287
Taking false branch
289
Assuming the condition is false
290
Assuming the condition is false
291
Taking false branch
293
Assuming the condition is false
294
Assuming the condition is false
295
Taking false branch
297
Assuming the condition is false
298
Assuming the condition is false
299
Taking false branch
301
Assuming the condition is true
302
The left operand of '==' is a garbage value
592 Val = ConstVal;
593 }
594 }
595
596 // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
597 template <typename T>
598 void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
599 if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
600 Val = ConstVal;
601 }
602 }
603
604 template <typename FBT, typename T>
605 void enumFallback(T &Val) {
606 if (matchEnumFallback()) {
607 EmptyContext Context;
608 // FIXME: Force integral conversion to allow strong typedefs to convert.
609 FBT Res = static_cast<typename FBT::BaseType>(Val);
610 yamlize(*this, Res, true, Context);
611 Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
612 }
613 }
614
615 template <typename T>
616 void bitSetCase(T &Val, const char* Str, const T ConstVal) {
617 if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
618 Val = static_cast<T>(Val | ConstVal);
619 }
620 }
621
622 // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
623 template <typename T>
624 void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
625 if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
626 Val = static_cast<T>(Val | ConstVal);
627 }
628 }
629
630 template <typename T>
631 void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
632 if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
633 Val = Val | ConstVal;
634 }
635
636 template <typename T>
637 void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
638 uint32_t Mask) {
639 if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
640 Val = Val | ConstVal;
641 }
642
643 void *getContext();
644 void setContext(void *);
645
646 template <typename T> void mapRequired(const char *Key, T &Val) {
647 EmptyContext Ctx;
5
Calling implicit default constructor for 'EmptyContext'
6
Returning from default constructor for 'EmptyContext'
648 this->processKey(Key, Val, true, Ctx);
7
Calling 'IO::processKey'
649 }
650
651 template <typename T, typename Context>
652 void mapRequired(const char *Key, T &Val, Context &Ctx) {
653 this->processKey(Key, Val, true, Ctx);
654 }
655
656 template <typename T> void mapOptional(const char *Key, T &Val) {
657 EmptyContext Ctx;
658 mapOptionalWithContext(Key, Val, Ctx);
659 }
660
661 template <typename T>
662 void mapOptional(const char *Key, T &Val, const T &Default) {
663 EmptyContext Ctx;
664 mapOptionalWithContext(Key, Val, Default, Ctx);
665 }
666
667 template <typename T, typename Context>
668 typename std::enable_if<has_SequenceTraits<T>::value, void>::type
669 mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
670 // omit key/value instead of outputting empty sequence
671 if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
672 return;
673 this->processKey(Key, Val, false, Ctx);
674 }
675
676 template <typename T, typename Context>
677 void mapOptionalWithContext(const char *Key, Optional<T> &Val, Context &Ctx) {
678 this->processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false,
679 Ctx);
680 }
681
682 template <typename T, typename Context>
683 typename std::enable_if<!has_SequenceTraits<T>::value, void>::type
684 mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
685 this->processKey(Key, Val, false, Ctx);
686 }
687
688 template <typename T, typename Context>
689 void mapOptionalWithContext(const char *Key, T &Val, const T &Default,
690 Context &Ctx) {
691 this->processKeyWithDefault(Key, Val, Default, false, Ctx);
692 }
693
694private:
695 template <typename T, typename Context>
696 void processKeyWithDefault(const char *Key, Optional<T> &Val,
697 const Optional<T> &DefaultValue, bool Required,
698 Context &Ctx) {
699 assert(DefaultValue.hasValue() == false &&(static_cast <bool> (DefaultValue.hasValue() == false &&
"Optional<T> shouldn't have a value!") ? void (0) : __assert_fail
("DefaultValue.hasValue() == false && \"Optional<T> shouldn't have a value!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/include/llvm/Support/YAMLTraits.h"
, 700, __extension__ __PRETTY_FUNCTION__))
700 "Optional<T> shouldn't have a value!")(static_cast <bool> (DefaultValue.hasValue() == false &&
"Optional<T> shouldn't have a value!") ? void (0) : __assert_fail
("DefaultValue.hasValue() == false && \"Optional<T> shouldn't have a value!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/include/llvm/Support/YAMLTraits.h"
, 700, __extension__ __PRETTY_FUNCTION__))
;
701 void *SaveInfo;
702 bool UseDefault = true;
703 const bool sameAsDefault = outputting() && !Val.hasValue();
704 if (!outputting() && !Val.hasValue())
705 Val = T();
706 if (Val.hasValue() &&
707 this->preflightKey(Key, Required, sameAsDefault, UseDefault,
708 SaveInfo)) {
709 yamlize(*this, Val.getValue(), Required, Ctx);
710 this->postflightKey(SaveInfo);
711 } else {
712 if (UseDefault)
713 Val = DefaultValue;
714 }
715 }
716
717 template <typename T, typename Context>
718 void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
719 bool Required, Context &Ctx) {
720 void *SaveInfo;
721 bool UseDefault;
722 const bool sameAsDefault = outputting() && Val == DefaultValue;
723 if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
724 SaveInfo) ) {
725 yamlize(*this, Val, Required, Ctx);
726 this->postflightKey(SaveInfo);
727 }
728 else {
729 if ( UseDefault )
730 Val = DefaultValue;
731 }
732 }
733
734 template <typename T, typename Context>
735 void processKey(const char *Key, T &Val, bool Required, Context &Ctx) {
736 void *SaveInfo;
737 bool UseDefault;
738 if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
8
Assuming the condition is true
9
Taking true branch
739 yamlize(*this, Val, Required, Ctx);
10
Calling 'yamlize'
740 this->postflightKey(SaveInfo);
741 }
742 }
743
744private:
745 void *Ctxt;
746};
747
748namespace detail {
749
750template <typename T, typename Context>
751void doMapping(IO &io, T &Val, Context &Ctx) {
752 MappingContextTraits<T, Context>::mapping(io, Val, Ctx);
753}
754
755template <typename T> void doMapping(IO &io, T &Val, EmptyContext &Ctx) {
756 MappingTraits<T>::mapping(io, Val);
757}
758
759} // end namespace detail
760
761template <typename T>
762typename std::enable_if<has_ScalarEnumerationTraits<T>::value, void>::type
763yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
764 io.beginEnumScalar();
765 ScalarEnumerationTraits<T>::enumeration(io, Val);
11
Calling 'ScalarEnumerationTraits::enumeration'
766 io.endEnumScalar();
767}
768
769template <typename T>
770typename std::enable_if<has_ScalarBitSetTraits<T>::value, void>::type
771yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
772 bool DoClear;
773 if ( io.beginBitSetScalar(DoClear) ) {
774 if ( DoClear )
775 Val = static_cast<T>(0);
776 ScalarBitSetTraits<T>::bitset(io, Val);
777 io.endBitSetScalar();
778 }
779}
780
781template <typename T>
782typename std::enable_if<has_ScalarTraits<T>::value, void>::type
783yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
784 if ( io.outputting() ) {
785 std::string Storage;
786 raw_string_ostream Buffer(Storage);
787 ScalarTraits<T>::output(Val, io.getContext(), Buffer);
788 StringRef Str = Buffer.str();
789 io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
790 }
791 else {
792 StringRef Str;
793 io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
794 StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
795 if ( !Result.empty() ) {
796 io.setError(Twine(Result));
797 }
798 }
799}
800
801template <typename T>
802typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type
803yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
804 if (YamlIO.outputting()) {
805 std::string Storage;
806 raw_string_ostream Buffer(Storage);
807 BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
808 StringRef Str = Buffer.str();
809 YamlIO.blockScalarString(Str);
810 } else {
811 StringRef Str;
812 YamlIO.blockScalarString(Str);
813 StringRef Result =
814 BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
815 if (!Result.empty())
816 YamlIO.setError(Twine(Result));
817 }
818}
819
820template <typename T, typename Context>
821typename std::enable_if<validatedMappingTraits<T, Context>::value, void>::type
822yamlize(IO &io, T &Val, bool, Context &Ctx) {
823 if (has_FlowTraits<MappingTraits<T>>::value)
824 io.beginFlowMapping();
825 else
826 io.beginMapping();
827 if (io.outputting()) {
828 StringRef Err = MappingTraits<T>::validate(io, Val);
829 if (!Err.empty()) {
830 errs() << Err << "\n";
831 assert(Err.empty() && "invalid struct trying to be written as yaml")(static_cast <bool> (Err.empty() && "invalid struct trying to be written as yaml"
) ? void (0) : __assert_fail ("Err.empty() && \"invalid struct trying to be written as yaml\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/include/llvm/Support/YAMLTraits.h"
, 831, __extension__ __PRETTY_FUNCTION__))
;
832 }
833 }
834 detail::doMapping(io, Val, Ctx);
835 if (!io.outputting()) {
836 StringRef Err = MappingTraits<T>::validate(io, Val);
837 if (!Err.empty())
838 io.setError(Err);
839 }
840 if (has_FlowTraits<MappingTraits<T>>::value)
841 io.endFlowMapping();
842 else
843 io.endMapping();
844}
845
846template <typename T, typename Context>
847typename std::enable_if<unvalidatedMappingTraits<T, Context>::value, void>::type
848yamlize(IO &io, T &Val, bool, Context &Ctx) {
849 if (has_FlowTraits<MappingTraits<T>>::value) {
850 io.beginFlowMapping();
851 detail::doMapping(io, Val, Ctx);
852 io.endFlowMapping();
853 } else {
854 io.beginMapping();
855 detail::doMapping(io, Val, Ctx);
856 io.endMapping();
857 }
858}
859
860template <typename T>
861typename std::enable_if<has_CustomMappingTraits<T>::value, void>::type
862yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
863 if ( io.outputting() ) {
864 io.beginMapping();
865 CustomMappingTraits<T>::output(io, Val);
866 io.endMapping();
867 } else {
868 io.beginMapping();
869 for (StringRef key : io.keys())
870 CustomMappingTraits<T>::inputOne(io, key, Val);
871 io.endMapping();
872 }
873}
874
875template <typename T>
876typename std::enable_if<missingTraits<T, EmptyContext>::value, void>::type
877yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
878 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
879}
880
881template <typename T, typename Context>
882typename std::enable_if<has_SequenceTraits<T>::value, void>::type
883yamlize(IO &io, T &Seq, bool, Context &Ctx) {
884 if ( has_FlowTraits< SequenceTraits<T>>::value ) {
885 unsigned incnt = io.beginFlowSequence();
886 unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
887 for(unsigned i=0; i < count; ++i) {
888 void *SaveInfo;
889 if ( io.preflightFlowElement(i, SaveInfo) ) {
890 yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
891 io.postflightFlowElement(SaveInfo);
892 }
893 }
894 io.endFlowSequence();
895 }
896 else {
897 unsigned incnt = io.beginSequence();
898 unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
899 for(unsigned i=0; i < count; ++i) {
900 void *SaveInfo;
901 if ( io.preflightElement(i, SaveInfo) ) {
902 yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
903 io.postflightElement(SaveInfo);
904 }
905 }
906 io.endSequence();
907 }
908}
909
910template<>
911struct ScalarTraits<bool> {
912 static void output(const bool &, void* , raw_ostream &);
913 static StringRef input(StringRef, void *, bool &);
914 static bool mustQuote(StringRef) { return false; }
915};
916
917template<>
918struct ScalarTraits<StringRef> {
919 static void output(const StringRef &, void *, raw_ostream &);
920 static StringRef input(StringRef, void *, StringRef &);
921 static bool mustQuote(StringRef S) { return needsQuotes(S); }
922};
923
924template<>
925struct ScalarTraits<std::string> {
926 static void output(const std::string &, void *, raw_ostream &);
927 static StringRef input(StringRef, void *, std::string &);
928 static bool mustQuote(StringRef S) { return needsQuotes(S); }
929};
930
931template<>
932struct ScalarTraits<uint8_t> {
933 static void output(const uint8_t &, void *, raw_ostream &);
934 static StringRef input(StringRef, void *, uint8_t &);
935 static bool mustQuote(StringRef) { return false; }
936};
937
938template<>
939struct ScalarTraits<uint16_t> {
940 static void output(const uint16_t &, void *, raw_ostream &);
941 static StringRef input(StringRef, void *, uint16_t &);
942 static bool mustQuote(StringRef) { return false; }
943};
944
945template<>
946struct ScalarTraits<uint32_t> {
947 static void output(const uint32_t &, void *, raw_ostream &);
948 static StringRef input(StringRef, void *, uint32_t &);
949 static bool mustQuote(StringRef) { return false; }
950};
951
952template<>
953struct ScalarTraits<uint64_t> {
954 static void output(const uint64_t &, void *, raw_ostream &);
955 static StringRef input(StringRef, void *, uint64_t &);
956 static bool mustQuote(StringRef) { return false; }
957};
958
959template<>
960struct ScalarTraits<int8_t> {
961 static void output(const int8_t &, void *, raw_ostream &);
962 static StringRef input(StringRef, void *, int8_t &);
963 static bool mustQuote(StringRef) { return false; }
964};
965
966template<>
967struct ScalarTraits<int16_t> {
968 static void output(const int16_t &, void *, raw_ostream &);
969 static StringRef input(StringRef, void *, int16_t &);
970 static bool mustQuote(StringRef) { return false; }
971};
972
973template<>
974struct ScalarTraits<int32_t> {
975 static void output(const int32_t &, void *, raw_ostream &);
976 static StringRef input(StringRef, void *, int32_t &);
977 static bool mustQuote(StringRef) { return false; }
978};
979
980template<>
981struct ScalarTraits<int64_t> {
982 static void output(const int64_t &, void *, raw_ostream &);
983 static StringRef input(StringRef, void *, int64_t &);
984 static bool mustQuote(StringRef) { return false; }
985};
986
987template<>
988struct ScalarTraits<float> {
989 static void output(const float &, void *, raw_ostream &);
990 static StringRef input(StringRef, void *, float &);
991 static bool mustQuote(StringRef) { return false; }
992};
993
994template<>
995struct ScalarTraits<double> {
996 static void output(const double &, void *, raw_ostream &);
997 static StringRef input(StringRef, void *, double &);
998 static bool mustQuote(StringRef) { return false; }
999};
1000
1001// For endian types, we just use the existing ScalarTraits for the underlying
1002// type. This way endian aware types are supported whenever a ScalarTraits
1003// is defined for the underlying type.
1004template <typename value_type, support::endianness endian, size_t alignment>
1005struct ScalarTraits<support::detail::packed_endian_specific_integral<
1006 value_type, endian, alignment>> {
1007 using endian_type =
1008 support::detail::packed_endian_specific_integral<value_type, endian,
1009 alignment>;
1010
1011 static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) {
1012 ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
1013 }
1014
1015 static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
1016 value_type V;
1017 auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
1018 E = static_cast<endian_type>(V);
1019 return R;
1020 }
1021
1022 static bool mustQuote(StringRef Str) {
1023 return ScalarTraits<value_type>::mustQuote(Str);
1024 }
1025};
1026
1027// Utility for use within MappingTraits<>::mapping() method
1028// to [de]normalize an object for use with YAML conversion.
1029template <typename TNorm, typename TFinal>
1030struct MappingNormalization {
1031 MappingNormalization(IO &i_o, TFinal &Obj)
1032 : io(i_o), BufPtr(nullptr), Result(Obj) {
1033 if ( io.outputting() ) {
1034 BufPtr = new (&Buffer) TNorm(io, Obj);
1035 }
1036 else {
1037 BufPtr = new (&Buffer) TNorm(io);
1038 }
1039 }
1040
1041 ~MappingNormalization() {
1042 if ( ! io.outputting() ) {
1043 Result = BufPtr->denormalize(io);
1044 }
1045 BufPtr->~TNorm();
1046 }
1047
1048 TNorm* operator->() { return BufPtr; }
1049
1050private:
1051 using Storage = AlignedCharArrayUnion<TNorm>;
1052
1053 Storage Buffer;
1054 IO &io;
1055 TNorm *BufPtr;
1056 TFinal &Result;
1057};
1058
1059// Utility for use within MappingTraits<>::mapping() method
1060// to [de]normalize an object for use with YAML conversion.
1061template <typename TNorm, typename TFinal>
1062struct MappingNormalizationHeap {
1063 MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator)
1064 : io(i_o), Result(Obj) {
1065 if ( io.outputting() ) {
1066 BufPtr = new (&Buffer) TNorm(io, Obj);
1067 }
1068 else if (allocator) {
1069 BufPtr = allocator->Allocate<TNorm>();
1070 new (BufPtr) TNorm(io);
1071 } else {
1072 BufPtr = new TNorm(io);
1073 }
1074 }
1075
1076 ~MappingNormalizationHeap() {
1077 if ( io.outputting() ) {
1078 BufPtr->~TNorm();
1079 }
1080 else {
1081 Result = BufPtr->denormalize(io);
1082 }
1083 }
1084
1085 TNorm* operator->() { return BufPtr; }
1086
1087private:
1088 using Storage = AlignedCharArrayUnion<TNorm>;
1089
1090 Storage Buffer;
1091 IO &io;
1092 TNorm *BufPtr = nullptr;
1093 TFinal &Result;
1094};
1095
1096///
1097/// The Input class is used to parse a yaml document into in-memory structs
1098/// and vectors.
1099///
1100/// It works by using YAMLParser to do a syntax parse of the entire yaml
1101/// document, then the Input class builds a graph of HNodes which wraps
1102/// each yaml Node. The extra layer is buffering. The low level yaml
1103/// parser only lets you look at each node once. The buffering layer lets
1104/// you search and interate multiple times. This is necessary because
1105/// the mapRequired() method calls may not be in the same order
1106/// as the keys in the document.
1107///
1108class Input : public IO {
1109public:
1110 // Construct a yaml Input object from a StringRef and optional
1111 // user-data. The DiagHandler can be specified to provide
1112 // alternative error reporting.
1113 Input(StringRef InputContent,
1114 void *Ctxt = nullptr,
1115 SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1116 void *DiagHandlerCtxt = nullptr);
1117 Input(MemoryBufferRef Input,
1118 void *Ctxt = nullptr,
1119 SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1120 void *DiagHandlerCtxt = nullptr);
1121 ~Input() override;
1122
1123 // Check if there was an syntax or semantic error during parsing.
1124 std::error_code error();
1125
1126private:
1127 bool outputting() override;
1128 bool mapTag(StringRef, bool) override;
1129 void beginMapping() override;
1130 void endMapping() override;
1131 bool preflightKey(const char *, bool, bool, bool &, void *&) override;
1132 void postflightKey(void *) override;
1133 std::vector<StringRef> keys() override;
1134 void beginFlowMapping() override;
1135 void endFlowMapping() override;
1136 unsigned beginSequence() override;
1137 void endSequence() override;
1138 bool preflightElement(unsigned index, void *&) override;
1139 void postflightElement(void *) override;
1140 unsigned beginFlowSequence() override;
1141 bool preflightFlowElement(unsigned , void *&) override;
1142 void postflightFlowElement(void *) override;
1143 void endFlowSequence() override;
1144 void beginEnumScalar() override;
1145 bool matchEnumScalar(const char*, bool) override;
1146 bool matchEnumFallback() override;
1147 void endEnumScalar() override;
1148 bool beginBitSetScalar(bool &) override;
1149 bool bitSetMatch(const char *, bool ) override;
1150 void endBitSetScalar() override;
1151 void scalarString(StringRef &, bool) override;
1152 void blockScalarString(StringRef &) override;
1153 void setError(const Twine &message) override;
1154 bool canElideEmptySequence() override;
1155
1156 class HNode {
1157 virtual void anchor();
1158
1159 public:
1160 HNode(Node *n) : _node(n) { }
1161 virtual ~HNode() = default;
1162
1163 static bool classof(const HNode *) { return true; }
1164
1165 Node *_node;
1166 };
1167
1168 class EmptyHNode : public HNode {
1169 void anchor() override;
1170
1171 public:
1172 EmptyHNode(Node *n) : HNode(n) { }
1173
1174 static bool classof(const HNode *n) { return NullNode::classof(n->_node); }
1175
1176 static bool classof(const EmptyHNode *) { return true; }
1177 };
1178
1179 class ScalarHNode : public HNode {
1180 void anchor() override;
1181
1182 public:
1183 ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
1184
1185 StringRef value() const { return _value; }
1186
1187 static bool classof(const HNode *n) {
1188 return ScalarNode::classof(n->_node) ||
1189 BlockScalarNode::classof(n->_node);
1190 }
1191
1192 static bool classof(const ScalarHNode *) { return true; }
1193
1194 protected:
1195 StringRef _value;
1196 };
1197
1198 class MapHNode : public HNode {
1199 void anchor() override;
1200
1201 public:
1202 MapHNode(Node *n) : HNode(n) { }
1203
1204 static bool classof(const HNode *n) {
1205 return MappingNode::classof(n->_node);
1206 }
1207
1208 static bool classof(const MapHNode *) { return true; }
1209
1210 using NameToNode = StringMap<std::unique_ptr<HNode>>;
1211
1212 NameToNode Mapping;
1213 SmallVector<std::string, 6> ValidKeys;
1214 };
1215
1216 class SequenceHNode : public HNode {
1217 void anchor() override;
1218
1219 public:
1220 SequenceHNode(Node *n) : HNode(n) { }
1221
1222 static bool classof(const HNode *n) {
1223 return SequenceNode::classof(n->_node);
1224 }
1225
1226 static bool classof(const SequenceHNode *) { return true; }
1227
1228 std::vector<std::unique_ptr<HNode>> Entries;
1229 };
1230
1231 std::unique_ptr<Input::HNode> createHNodes(Node *node);
1232 void setError(HNode *hnode, const Twine &message);
1233 void setError(Node *node, const Twine &message);
1234
1235public:
1236 // These are only used by operator>>. They could be private
1237 // if those templated things could be made friends.
1238 bool setCurrentDocument();
1239 bool nextDocument();
1240
1241 /// Returns the current node that's being parsed by the YAML Parser.
1242 const Node *getCurrentNode() const;
1243
1244private:
1245 SourceMgr SrcMgr; // must be before Strm
1246 std::unique_ptr<llvm::yaml::Stream> Strm;
1247 std::unique_ptr<HNode> TopNode;
1248 std::error_code EC;
1249 BumpPtrAllocator StringAllocator;
1250 document_iterator DocIterator;
1251 std::vector<bool> BitValuesUsed;
1252 HNode *CurrentNode = nullptr;
1253 bool ScalarMatchFound;
1254};
1255
1256///
1257/// The Output class is used to generate a yaml document from in-memory structs
1258/// and vectors.
1259///
1260class Output : public IO {
1261public:
1262 Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
1263 ~Output() override;
1264
1265 /// \brief Set whether or not to output optional values which are equal
1266 /// to the default value. By default, when outputting if you attempt
1267 /// to write a value that is equal to the default, the value gets ignored.
1268 /// Sometimes, it is useful to be able to see these in the resulting YAML
1269 /// anyway.
1270 void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }
1271
1272 bool outputting() override;
1273 bool mapTag(StringRef, bool) override;
1274 void beginMapping() override;
1275 void endMapping() override;
1276 bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
1277 void postflightKey(void *) override;
1278 std::vector<StringRef> keys() override;
1279 void beginFlowMapping() override;
1280 void endFlowMapping() override;
1281 unsigned beginSequence() override;
1282 void endSequence() override;
1283 bool preflightElement(unsigned, void *&) override;
1284 void postflightElement(void *) override;
1285 unsigned beginFlowSequence() override;
1286 bool preflightFlowElement(unsigned, void *&) override;
1287 void postflightFlowElement(void *) override;
1288 void endFlowSequence() override;
1289 void beginEnumScalar() override;
1290 bool matchEnumScalar(const char*, bool) override;
1291 bool matchEnumFallback() override;
1292 void endEnumScalar() override;
1293 bool beginBitSetScalar(bool &) override;
1294 bool bitSetMatch(const char *, bool ) override;
1295 void endBitSetScalar() override;
1296 void scalarString(StringRef &, bool) override;
1297 void blockScalarString(StringRef &) override;
1298 void setError(const Twine &message) override;
1299 bool canElideEmptySequence() override;
1300
1301 // These are only used by operator<<. They could be private
1302 // if that templated operator could be made a friend.
1303 void beginDocuments();
1304 bool preflightDocument(unsigned);
1305 void postflightDocument();
1306 void endDocuments();
1307
1308private:
1309 void output(StringRef s);
1310 void outputUpToEndOfLine(StringRef s);
1311 void newLineCheck();
1312 void outputNewLine();
1313 void paddedKey(StringRef key);
1314 void flowKey(StringRef Key);
1315
1316 enum InState {
1317 inSeq,
1318 inFlowSeq,
1319 inMapFirstKey,
1320 inMapOtherKey,
1321 inFlowMapFirstKey,
1322 inFlowMapOtherKey
1323 };
1324
1325 raw_ostream &Out;
1326 int WrapColumn;
1327 SmallVector<InState, 8> StateStack;
1328 int Column = 0;
1329 int ColumnAtFlowStart = 0;
1330 int ColumnAtMapFlowStart = 0;
1331 bool NeedBitValueComma = false;
1332 bool NeedFlowSequenceComma = false;
1333 bool EnumerationMatchFound = false;
1334 bool NeedsNewLine = false;
1335 bool WriteDefaultValues = false;
1336};
1337
1338/// YAML I/O does conversion based on types. But often native data types
1339/// are just a typedef of built in intergral types (e.g. int). But the C++
1340/// type matching system sees through the typedef and all the typedefed types
1341/// look like a built in type. This will cause the generic YAML I/O conversion
1342/// to be used. To provide better control over the YAML conversion, you can
1343/// use this macro instead of typedef. It will create a class with one field
1344/// and automatic conversion operators to and from the base type.
1345/// Based on BOOST_STRONG_TYPEDEF
1346#define LLVM_YAML_STRONG_TYPEDEF(_base, _type)struct _type { _type() = default; _type(const _base v) : value
(v) {} _type(const _type &v) = default; _type &operator
=(const _type &rhs) = default; _type &operator=(const
_base &rhs) { value = rhs; return *this; } operator const
_base & () const { return value; } bool operator==(const
_type &rhs) const { return value == rhs.value; } bool operator
==(const _base &rhs) const { return value == rhs; } bool operator
<(const _type &rhs) const { return value < rhs.value
; } _base value; using BaseType = _base; };
\
1347 struct _type { \
1348 _type() = default; \
1349 _type(const _base v) : value(v) {} \
1350 _type(const _type &v) = default; \
1351 _type &operator=(const _type &rhs) = default; \
1352 _type &operator=(const _base &rhs) { value = rhs; return *this; } \
1353 operator const _base & () const { return value; } \
1354 bool operator==(const _type &rhs) const { return value == rhs.value; } \
1355 bool operator==(const _base &rhs) const { return value == rhs; } \
1356 bool operator<(const _type &rhs) const { return value < rhs.value; } \
1357 _base value; \
1358 using BaseType = _base; \
1359 };
1360
1361///
1362/// Use these types instead of uintXX_t in any mapping to have
1363/// its yaml output formatted as hexadecimal.
1364///
1365LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)struct Hex8 { Hex8() = default; Hex8(const uint8_t v) : value
(v) {} Hex8(const Hex8 &v) = default; Hex8 &operator=
(const Hex8 &rhs) = default; Hex8 &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const Hex8 &
rhs) const { return value == rhs.value; } bool operator==(const
uint8_t &rhs) const { return value == rhs; } bool operator
<(const Hex8 &rhs) const { return value < rhs.value
; } uint8_t value; using BaseType = uint8_t; };
1366LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)struct Hex16 { Hex16() = default; Hex16(const uint16_t v) : value
(v) {} Hex16(const Hex16 &v) = default; Hex16 &operator
=(const Hex16 &rhs) = default; Hex16 &operator=(const
uint16_t &rhs) { value = rhs; return *this; } operator const
uint16_t & () const { return value; } bool operator==(const
Hex16 &rhs) const { return value == rhs.value; } bool operator
==(const uint16_t &rhs) const { return value == rhs; } bool
operator<(const Hex16 &rhs) const { return value <
rhs.value; } uint16_t value; using BaseType = uint16_t; };
1367LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)struct Hex32 { Hex32() = default; Hex32(const uint32_t v) : value
(v) {} Hex32(const Hex32 &v) = default; Hex32 &operator
=(const Hex32 &rhs) = default; Hex32 &operator=(const
uint32_t &rhs) { value = rhs; return *this; } operator const
uint32_t & () const { return value; } bool operator==(const
Hex32 &rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const Hex32 &rhs) const { return value <
rhs.value; } uint32_t value; using BaseType = uint32_t; };
1368LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)struct Hex64 { Hex64() = default; Hex64(const uint64_t v) : value
(v) {} Hex64(const Hex64 &v) = default; Hex64 &operator
=(const Hex64 &rhs) = default; Hex64 &operator=(const
uint64_t &rhs) { value = rhs; return *this; } operator const
uint64_t & () const { return value; } bool operator==(const
Hex64 &rhs) const { return value == rhs.value; } bool operator
==(const uint64_t &rhs) const { return value == rhs; } bool
operator<(const Hex64 &rhs) const { return value <
rhs.value; } uint64_t value; using BaseType = uint64_t; };
1369
1370template<>
1371struct ScalarTraits<Hex8> {
1372 static void output(const Hex8 &, void *, raw_ostream &);
1373 static StringRef input(StringRef, void *, Hex8 &);
1374 static bool mustQuote(StringRef) { return false; }
1375};
1376
1377template<>
1378struct ScalarTraits<Hex16> {
1379 static void output(const Hex16 &, void *, raw_ostream &);
1380 static StringRef input(StringRef, void *, Hex16 &);
1381 static bool mustQuote(StringRef) { return false; }
1382};
1383
1384template<>
1385struct ScalarTraits<Hex32> {
1386 static void output(const Hex32 &, void *, raw_ostream &);
1387 static StringRef input(StringRef, void *, Hex32 &);
1388 static bool mustQuote(StringRef) { return false; }
1389};
1390
1391template<>
1392struct ScalarTraits<Hex64> {
1393 static void output(const Hex64 &, void *, raw_ostream &);
1394 static StringRef input(StringRef, void *, Hex64 &);
1395 static bool mustQuote(StringRef) { return false; }
1396};
1397
1398// Define non-member operator>> so that Input can stream in a document list.
1399template <typename T>
1400inline
1401typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
1402operator>>(Input &yin, T &docList) {
1403 int i = 0;
1404 EmptyContext Ctx;
1405 while ( yin.setCurrentDocument() ) {
1406 yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
1407 if ( yin.error() )
1408 return yin;
1409 yin.nextDocument();
1410 ++i;
1411 }
1412 return yin;
1413}
1414
1415// Define non-member operator>> so that Input can stream in a map as a document.
1416template <typename T>
1417inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1418 Input &>::type
1419operator>>(Input &yin, T &docMap) {
1420 EmptyContext Ctx;
1421 yin.setCurrentDocument();
1422 yamlize(yin, docMap, true, Ctx);
1423 return yin;
1424}
1425
1426// Define non-member operator>> so that Input can stream in a sequence as
1427// a document.
1428template <typename T>
1429inline
1430typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
1431operator>>(Input &yin, T &docSeq) {
1432 EmptyContext Ctx;
1433 if (yin.setCurrentDocument())
1434 yamlize(yin, docSeq, true, Ctx);
1435 return yin;
1436}
1437
1438// Define non-member operator>> so that Input can stream in a block scalar.
1439template <typename T>
1440inline
1441typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
1442operator>>(Input &In, T &Val) {
1443 EmptyContext Ctx;
1444 if (In.setCurrentDocument())
1445 yamlize(In, Val, true, Ctx);
1446 return In;
1447}
1448
1449// Define non-member operator>> so that Input can stream in a string map.
1450template <typename T>
1451inline
1452typename std::enable_if<has_CustomMappingTraits<T>::value, Input &>::type
1453operator>>(Input &In, T &Val) {
1454 EmptyContext Ctx;
1455 if (In.setCurrentDocument())
1456 yamlize(In, Val, true, Ctx);
1457 return In;
1458}
1459
1460// Provide better error message about types missing a trait specialization
1461template <typename T>
1462inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1463 Input &>::type
1464operator>>(Input &yin, T &docSeq) {
1465 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1466 return yin;
1467}
1468
1469// Define non-member operator<< so that Output can stream out document list.
1470template <typename T>
1471inline
1472typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
1473operator<<(Output &yout, T &docList) {
1474 EmptyContext Ctx;
1475 yout.beginDocuments();
1476 const size_t count = DocumentListTraits<T>::size(yout, docList);
1477 for(size_t i=0; i < count; ++i) {
1478 if ( yout.preflightDocument(i) ) {
1479 yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
1480 Ctx);
1481 yout.postflightDocument();
1482 }
1483 }
1484 yout.endDocuments();
1485 return yout;
1486}
1487
1488// Define non-member operator<< so that Output can stream out a map.
1489template <typename T>
1490inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1491 Output &>::type
1492operator<<(Output &yout, T &map) {
1493 EmptyContext Ctx;
1494 yout.beginDocuments();
1495 if ( yout.preflightDocument(0) ) {
1496 yamlize(yout, map, true, Ctx);
1497 yout.postflightDocument();
1498 }
1499 yout.endDocuments();
1500 return yout;
1501}
1502
1503// Define non-member operator<< so that Output can stream out a sequence.
1504template <typename T>
1505inline
1506typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
1507operator<<(Output &yout, T &seq) {
1508 EmptyContext Ctx;
1509 yout.beginDocuments();
1510 if ( yout.preflightDocument(0) ) {
1511 yamlize(yout, seq, true, Ctx);
1512 yout.postflightDocument();
1513 }
1514 yout.endDocuments();
1515 return yout;
1516}
1517
1518// Define non-member operator<< so that Output can stream out a block scalar.
1519template <typename T>
1520inline
1521typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
1522operator<<(Output &Out, T &Val) {
1523 EmptyContext Ctx;
1524 Out.beginDocuments();
1525 if (Out.preflightDocument(0)) {
1526 yamlize(Out, Val, true, Ctx);
1527 Out.postflightDocument();
1528 }
1529 Out.endDocuments();
1530 return Out;
1531}
1532
1533// Define non-member operator<< so that Output can stream out a string map.
1534template <typename T>
1535inline
1536typename std::enable_if<has_CustomMappingTraits<T>::value, Output &>::type
1537operator<<(Output &Out, T &Val) {
1538 EmptyContext Ctx;
1539 Out.beginDocuments();
1540 if (Out.preflightDocument(0)) {
1541 yamlize(Out, Val, true, Ctx);
1542 Out.postflightDocument();
1543 }
1544 Out.endDocuments();
1545 return Out;
1546}
1547
1548// Provide better error message about types missing a trait specialization
1549template <typename T>
1550inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1551 Output &>::type
1552operator<<(Output &yout, T &seq) {
1553 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1554 return yout;
1555}
1556
1557template <bool B> struct IsFlowSequenceBase {};
1558template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
1559
1560template <typename T, bool Flow>
1561struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
1562private:
1563 using type = typename T::value_type;
1564
1565public:
1566 static size_t size(IO &io, T &seq) { return seq.size(); }
1567
1568 static type &element(IO &io, T &seq, size_t index) {
1569 if (index >= seq.size())
1570 seq.resize(index + 1);
1571 return seq[index];
1572 }
1573};
1574
1575// Simple helper to check an expression can be used as a bool-valued template
1576// argument.
1577template <bool> struct CheckIsBool { static const bool value = true; };
1578
1579// If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
1580// SequenceTraits that do the obvious thing.
1581template <typename T>
1582struct SequenceTraits<std::vector<T>,
1583 typename std::enable_if<CheckIsBool<
1584 SequenceElementTraits<T>::flow>::value>::type>
1585 : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
1586template <typename T, unsigned N>
1587struct SequenceTraits<SmallVector<T, N>,
1588 typename std::enable_if<CheckIsBool<
1589 SequenceElementTraits<T>::flow>::value>::type>
1590 : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
1591
1592// Sequences of fundamental types use flow formatting.
1593template <typename T>
1594struct SequenceElementTraits<
1595 T, typename std::enable_if<std::is_fundamental<T>::value>::type> {
1596 static const bool flow = true;
1597};
1598
1599// Sequences of strings use block formatting.
1600template<> struct SequenceElementTraits<std::string> {
1601 static const bool flow = false;
1602};
1603template<> struct SequenceElementTraits<StringRef> {
1604 static const bool flow = false;
1605};
1606template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
1607 static const bool flow = false;
1608};
1609
1610/// Implementation of CustomMappingTraits for std::map<std::string, T>.
1611template <typename T> struct StdMapStringCustomMappingTraitsImpl {
1612 using map_type = std::map<std::string, T>;
1613
1614 static void inputOne(IO &io, StringRef key, map_type &v) {
1615 io.mapRequired(key.str().c_str(), v[key]);
1616 }
1617
1618 static void output(IO &io, map_type &v) {
1619 for (auto &p : v)
1620 io.mapRequired(p.first.c_str(), p.second);
1621 }
1622};
1623
1624} // end namespace yaml
1625} // end namespace llvm
1626
1627#define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<TYPE>::value && !std::is_same<TYPE, std::string
>::value && !std::is_same<TYPE, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<TYPE>
{ static const bool flow = FLOW; }; } }
\
1628 namespace llvm { \
1629 namespace yaml { \
1630 static_assert( \
1631 !std::is_fundamental<TYPE>::value && \
1632 !std::is_same<TYPE, std::string>::value && \
1633 !std::is_same<TYPE, llvm::StringRef>::value, \
1634 "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"); \
1635 template <> struct SequenceElementTraits<TYPE> { \
1636 static const bool flow = FLOW; \
1637 }; \
1638 } \
1639 }
1640
1641/// Utility for declaring that a std::vector of a particular type
1642/// should be considered a YAML sequence.
1643#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = false; }; } }
\
1644 LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = false; }; } }
1645
1646/// Utility for declaring that a std::vector of a particular type
1647/// should be considered a YAML flow sequence.
1648#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = true; }; } }
\
1649 LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = true; }; } }
1650
1651#define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type)namespace llvm { namespace yaml { template <> struct MappingTraits
<Type> { static void mapping(IO &IO, Type &Obj)
; }; } }
\
1652 namespace llvm { \
1653 namespace yaml { \
1654 template <> struct MappingTraits<Type> { \
1655 static void mapping(IO &IO, Type &Obj); \
1656 }; \
1657 } \
1658 }
1659
1660#define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<Type> { static void enumeration(IO &io, Type &
Value); }; } }
\
1661 namespace llvm { \
1662 namespace yaml { \
1663 template <> struct ScalarEnumerationTraits<Type> { \
1664 static void enumeration(IO &io, Type &Value); \
1665 }; \
1666 } \
1667 }
1668
1669#define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)namespace llvm { namespace yaml { template <> struct ScalarBitSetTraits
<Type> { static void bitset(IO &IO, Type &Options
); }; } }
\
1670 namespace llvm { \
1671 namespace yaml { \
1672 template <> struct ScalarBitSetTraits<Type> { \
1673 static void bitset(IO &IO, Type &Options); \
1674 }; \
1675 } \
1676 }
1677
1678#define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote)namespace llvm { namespace yaml { template <> struct ScalarTraits
<Type> { static void output(const Type &Value, void
*ctx, raw_ostream &Out); static StringRef input(StringRef
Scalar, void *ctxt, Type &Value); static bool mustQuote(
StringRef) { return MustQuote; } }; } }
\
1679 namespace llvm { \
1680 namespace yaml { \
1681 template <> struct ScalarTraits<Type> { \
1682 static void output(const Type &Value, void *ctx, raw_ostream &Out); \
1683 static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \
1684 static bool mustQuote(StringRef) { return MustQuote; } \
1685 }; \
1686 } \
1687 }
1688
1689/// Utility for declaring that a std::vector of a particular type
1690/// should be considered a YAML document list.
1691#define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type)namespace llvm { namespace yaml { template <unsigned N>
struct DocumentListTraits<SmallVector<_type, N>>
: public SequenceTraitsImpl<SmallVector<_type, N>, false
> {}; template <> struct DocumentListTraits<std::
vector<_type>> : public SequenceTraitsImpl<std::vector
<_type>, false> {}; } }
\
1692 namespace llvm { \
1693 namespace yaml { \
1694 template <unsigned N> \
1695 struct DocumentListTraits<SmallVector<_type, N>> \
1696 : public SequenceTraitsImpl<SmallVector<_type, N>, false> {}; \
1697 template <> \
1698 struct DocumentListTraits<std::vector<_type>> \
1699 : public SequenceTraitsImpl<std::vector<_type>, false> {}; \
1700 } \
1701 }
1702
1703/// Utility for declaring that std::map<std::string, _type> should be considered
1704/// a YAML map.
1705#define LLVM_YAML_IS_STRING_MAP(_type)namespace llvm { namespace yaml { template <> struct CustomMappingTraits
<std::map<std::string, _type>> : public StdMapStringCustomMappingTraitsImpl
<_type> {}; } }
\
1706 namespace llvm { \
1707 namespace yaml { \
1708 template <> \
1709 struct CustomMappingTraits<std::map<std::string, _type>> \
1710 : public StdMapStringCustomMappingTraitsImpl<_type> {}; \
1711 } \
1712 }
1713
1714#endif // LLVM_SUPPORT_YAMLTRAITS_H

/build/llvm-toolchain-snapshot-6.0~svn318601/include/llvm/DebugInfo/CodeView/CodeViewTypes.def

1//===-- CodeViewTypes.def - All CodeView leaf types -------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// See LEAF_ENUM_e in cvinfo.h. This should match the constants there.
11//
12//===----------------------------------------------------------------------===//
13
14// If the type is known, then we have a record describing it in TypeRecord.h.
15
16#ifndef CV_TYPE
17#define CV_TYPE(lf_ename, value)
18#endif
19
20// If the type is known, then we have a record describing it in TypeRecord.h.
21#ifndef TYPE_RECORD
22#define TYPE_RECORD(lf_ename, value, name) CV_TYPE(lf_ename, value)
23#endif
24
25#ifndef TYPE_RECORD_ALIAS
26#define TYPE_RECORD_ALIAS(lf_ename, value, name, alias_name) \
27 TYPE_RECORD(lf_ename, value, name)
28#endif
29
30#ifndef MEMBER_RECORD
31#define MEMBER_RECORD(lf_ename, value, name) TYPE_RECORD(lf_ename, value, name)
32#endif
33
34#ifndef MEMBER_RECORD_ALIAS
35#define MEMBER_RECORD_ALIAS(lf_ename, value, name, alias_name) \
36 MEMBER_RECORD(lf_ename, value, name)
37#endif
38
39TYPE_RECORD(LF_POINTER, 0x1002, Pointer)
12
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
40TYPE_RECORD(LF_MODIFIER, 0x1001, Modifier)
16
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
41TYPE_RECORD(LF_PROCEDURE, 0x1008, Procedure)
20
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
42TYPE_RECORD(LF_MFUNCTION, 0x1009, MemberFunction)
24
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
43TYPE_RECORD(LF_LABEL, 0x000e, Label)
28
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
44TYPE_RECORD(LF_ARGLIST, 0x1201, ArgList)
32
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
45
46TYPE_RECORD(LF_FIELDLIST, 0x1203, FieldList)
36
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
47
48TYPE_RECORD(LF_ARRAY, 0x1503, Array)
40
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
49TYPE_RECORD(LF_CLASS, 0x1504, Class)
44
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
50TYPE_RECORD_ALIAS(LF_STRUCTURE, 0x1505, Struct, Class)
48
Within the expansion of the macro 'TYPE_RECORD_ALIAS':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
51TYPE_RECORD_ALIAS(LF_INTERFACE, 0x1519, Interface, Class)
52
Within the expansion of the macro 'TYPE_RECORD_ALIAS':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
52TYPE_RECORD(LF_UNION, 0x1506, Union)
56
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
53TYPE_RECORD(LF_ENUM, 0x1507, Enum)
60
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
54TYPE_RECORD(LF_TYPESERVER2, 0x1515, TypeServer2)
64
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
55TYPE_RECORD(LF_VFTABLE, 0x151d, VFTable)
68
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
56TYPE_RECORD(LF_VTSHAPE, 0x000a, VFTableShape)
72
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
57
58TYPE_RECORD(LF_BITFIELD, 0x1205, BitField)
76
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
59
60// Member type records. These are generally not length prefixed, and appear
61// inside of a field list record.
62MEMBER_RECORD(LF_BCLASS, 0x1400, BaseClass)
80
Within the expansion of the macro 'MEMBER_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
63MEMBER_RECORD_ALIAS(LF_BINTERFACE, 0x151a, BaseInterface, BaseClass)
84
Within the expansion of the macro 'MEMBER_RECORD_ALIAS':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
64
65MEMBER_RECORD(LF_VBCLASS, 0x1401, VirtualBaseClass)
88
Within the expansion of the macro 'MEMBER_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
66MEMBER_RECORD_ALIAS(LF_IVBCLASS, 0x1402, IndirectVirtualBaseClass,
92
Within the expansion of the macro 'MEMBER_RECORD_ALIAS':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
67 VirtualBaseClass)
68
69MEMBER_RECORD(LF_VFUNCTAB, 0x1409, VFPtr)
96
Within the expansion of the macro 'MEMBER_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
70MEMBER_RECORD(LF_STMEMBER, 0x150e, StaticDataMember)
100
Within the expansion of the macro 'MEMBER_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
71MEMBER_RECORD(LF_METHOD, 0x150f, OverloadedMethod)
104
Within the expansion of the macro 'MEMBER_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
72MEMBER_RECORD(LF_MEMBER, 0x150d, DataMember)
108
Within the expansion of the macro 'MEMBER_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
73MEMBER_RECORD(LF_NESTTYPE, 0x1510, NestedType)
112
Within the expansion of the macro 'MEMBER_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
74MEMBER_RECORD(LF_ONEMETHOD, 0x1511, OneMethod)
116
Within the expansion of the macro 'MEMBER_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
75MEMBER_RECORD(LF_ENUMERATE, 0x1502, Enumerator)
120
Within the expansion of the macro 'MEMBER_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
76MEMBER_RECORD(LF_INDEX, 0x1404, ListContinuation)
124
Within the expansion of the macro 'MEMBER_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
77
78// ID leaf records. Subsequent leaf types may be referenced from .debug$S.
79TYPE_RECORD(LF_FUNC_ID, 0x1601, FuncId)
128
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
80TYPE_RECORD(LF_MFUNC_ID, 0x1602, MemberFuncId)
132
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
81TYPE_RECORD(LF_BUILDINFO, 0x1603, BuildInfo)
136
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
82TYPE_RECORD(LF_SUBSTR_LIST, 0x1604, StringList)
140
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
83TYPE_RECORD(LF_STRING_ID, 0x1605, StringId)
144
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
84TYPE_RECORD(LF_UDT_SRC_LINE, 0x1606, UdtSourceLine)
148
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
85TYPE_RECORD(LF_UDT_MOD_SRC_LINE, 0x1607, UdtModSourceLine)
152
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
86
87
88TYPE_RECORD(LF_METHODLIST, 0x1206, MethodOverloadList)
156
Within the expansion of the macro 'TYPE_RECORD':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
89
90
91// 16 bit type records.
92CV_TYPE(LF_MODIFIER_16t, 0x0001)
160
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
93CV_TYPE(LF_POINTER_16t, 0x0002)
164
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
94CV_TYPE(LF_ARRAY_16t, 0x0003)
168
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
95CV_TYPE(LF_CLASS_16t, 0x0004)
172
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
96CV_TYPE(LF_STRUCTURE_16t, 0x0005)
176
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
97CV_TYPE(LF_UNION_16t, 0x0006)
180
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
98CV_TYPE(LF_ENUM_16t, 0x0007)
184
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
99CV_TYPE(LF_PROCEDURE_16t, 0x0008)
188
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
100CV_TYPE(LF_MFUNCTION_16t, 0x0009)
192
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
101CV_TYPE(LF_COBOL0_16t, 0x000b)
196
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
102CV_TYPE(LF_COBOL1, 0x000c)
200
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
103CV_TYPE(LF_BARRAY_16t, 0x000d)
204
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
104CV_TYPE(LF_NULLLEAF, 0x000f) // LF_NULL
208
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
105CV_TYPE(LF_NOTTRAN, 0x0010)
212
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
106CV_TYPE(LF_DIMARRAY_16t, 0x0011)
216
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
107CV_TYPE(LF_VFTPATH_16t, 0x0012)
220
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
108CV_TYPE(LF_PRECOMP_16t, 0x0013)
224
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
109CV_TYPE(LF_ENDPRECOMP, 0x0014)
228
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
110CV_TYPE(LF_OEM_16t, 0x0015)
232
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
111CV_TYPE(LF_TYPESERVER_ST, 0x0016)
236
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
112
113CV_TYPE(LF_SKIP_16t, 0x0200)
240
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
114CV_TYPE(LF_ARGLIST_16t, 0x0201)
244
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
115CV_TYPE(LF_DEFARG_16t, 0x0202)
248
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
116CV_TYPE(LF_LIST, 0x0203)
252
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
117CV_TYPE(LF_FIELDLIST_16t, 0x0204)
256
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
118CV_TYPE(LF_DERIVED_16t, 0x0205)
260
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
119CV_TYPE(LF_BITFIELD_16t, 0x0206)
264
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
120CV_TYPE(LF_METHODLIST_16t, 0x0207)
268
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
121CV_TYPE(LF_DIMCONU_16t, 0x0208)
272
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
122CV_TYPE(LF_DIMCONLU_16t, 0x0209)
276
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
123CV_TYPE(LF_DIMVARU_16t, 0x020a)
280
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
124CV_TYPE(LF_DIMVARLU_16t, 0x020b)
284
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
125CV_TYPE(LF_REFSYM, 0x020c)
288
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
126
127// 16 bit member types. Generally not length prefixed.
128CV_TYPE(LF_BCLASS_16t, 0x0400)
292
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
129CV_TYPE(LF_VBCLASS_16t, 0x0401)
296
Within the expansion of the macro 'CV_TYPE':
a
Calling 'IO::enumCase'
b
Returning from 'IO::enumCase'
130CV_TYPE(LF_IVBCLASS_16t, 0x0402)
300
Within the expansion of the macro 'CV_TYPE':
a
Passing value via 1st parameter 'Val'
b
Calling 'IO::enumCase'
131CV_TYPE(LF_ENUMERATE_ST, 0x0403)
132CV_TYPE(LF_FRIENDFCN_16t, 0x0404)
133CV_TYPE(LF_INDEX_16t, 0x0405)
134CV_TYPE(LF_MEMBER_16t, 0x0406)
135CV_TYPE(LF_STMEMBER_16t, 0x0407)
136CV_TYPE(LF_METHOD_16t, 0x0408)
137CV_TYPE(LF_NESTTYPE_16t, 0x0409)
138CV_TYPE(LF_VFUNCTAB_16t, 0x040a)
139CV_TYPE(LF_FRIENDCLS_16t, 0x040b)
140CV_TYPE(LF_ONEMETHOD_16t, 0x040c)
141CV_TYPE(LF_VFUNCOFF_16t, 0x040d)
142
143CV_TYPE(LF_TI16_MAX, 0x1000)
144
145CV_TYPE(LF_ARRAY_ST, 0x1003)
146CV_TYPE(LF_CLASS_ST, 0x1004)
147CV_TYPE(LF_STRUCTURE_ST, 0x1005)
148CV_TYPE(LF_UNION_ST, 0x1006)
149CV_TYPE(LF_ENUM_ST, 0x1007)
150CV_TYPE(LF_COBOL0, 0x100a)
151CV_TYPE(LF_BARRAY, 0x100b)
152CV_TYPE(LF_DIMARRAY_ST, 0x100c)
153CV_TYPE(LF_VFTPATH, 0x100d)
154CV_TYPE(LF_PRECOMP_ST, 0x100e)
155CV_TYPE(LF_OEM, 0x100f)
156CV_TYPE(LF_ALIAS_ST, 0x1010)
157CV_TYPE(LF_OEM2, 0x1011)
158
159CV_TYPE(LF_SKIP, 0x1200)
160CV_TYPE(LF_DEFARG_ST, 0x1202)
161CV_TYPE(LF_DERIVED, 0x1204)
162CV_TYPE(LF_DIMCONU, 0x1207)
163CV_TYPE(LF_DIMCONLU, 0x1208)
164CV_TYPE(LF_DIMVARU, 0x1209)
165CV_TYPE(LF_DIMVARLU, 0x120a)
166
167// Member type records. These are generally not length prefixed, and appear
168// inside of a field list record.
169CV_TYPE(LF_FRIENDFCN_ST, 0x1403)
170CV_TYPE(LF_MEMBER_ST, 0x1405)
171CV_TYPE(LF_STMEMBER_ST, 0x1406)
172CV_TYPE(LF_METHOD_ST, 0x1407)
173CV_TYPE(LF_NESTTYPE_ST, 0x1408)
174CV_TYPE(LF_FRIENDCLS, 0x140a)
175CV_TYPE(LF_ONEMETHOD_ST, 0x140b)
176CV_TYPE(LF_VFUNCOFF, 0x140c)
177CV_TYPE(LF_NESTTYPEEX_ST, 0x140d)
178CV_TYPE(LF_MEMBERMODIFY_ST, 0x140e)
179CV_TYPE(LF_MANAGED_ST, 0x140f)
180
181CV_TYPE(LF_ST_MAX, 0x1500)
182CV_TYPE(LF_TYPESERVER, 0x1501)
183CV_TYPE(LF_DIMARRAY, 0x1508)
184CV_TYPE(LF_PRECOMP, 0x1509)
185CV_TYPE(LF_ALIAS, 0x150a)
186CV_TYPE(LF_DEFARG, 0x150b)
187CV_TYPE(LF_FRIENDFCN, 0x150c)
188CV_TYPE(LF_NESTTYPEEX, 0x1512)
189CV_TYPE(LF_MEMBERMODIFY, 0x1513)
190CV_TYPE(LF_MANAGED, 0x1514)
191CV_TYPE(LF_STRIDED_ARRAY, 0x1516)
192CV_TYPE(LF_HLSL, 0x1517)
193CV_TYPE(LF_MODIFIER_EX, 0x1518)
194CV_TYPE(LF_VECTOR, 0x151b)
195CV_TYPE(LF_MATRIX, 0x151c)
196
197// ID leaf records. Subsequent leaf types may be referenced from .debug$S.
198
199// Numeric leaf types. These are generally contained in other records, and not
200// encountered in the main type stream.
201
202CV_TYPE(LF_NUMERIC, 0x8000)
203CV_TYPE(LF_CHAR, 0x8000)
204CV_TYPE(LF_SHORT, 0x8001)
205CV_TYPE(LF_USHORT, 0x8002)
206CV_TYPE(LF_LONG, 0x8003)
207CV_TYPE(LF_ULONG, 0x8004)
208CV_TYPE(LF_REAL32, 0x8005)
209CV_TYPE(LF_REAL64, 0x8006)
210CV_TYPE(LF_REAL80, 0x8007)
211CV_TYPE(LF_REAL128, 0x8008)
212CV_TYPE(LF_QUADWORD, 0x8009)
213CV_TYPE(LF_UQUADWORD, 0x800a)
214CV_TYPE(LF_REAL48, 0x800b)
215CV_TYPE(LF_COMPLEX32, 0x800c)
216CV_TYPE(LF_COMPLEX64, 0x800d)
217CV_TYPE(LF_COMPLEX80, 0x800e)
218CV_TYPE(LF_COMPLEX128, 0x800f)
219CV_TYPE(LF_VARSTRING, 0x8010)
220CV_TYPE(LF_OCTWORD, 0x8017)
221CV_TYPE(LF_UOCTWORD, 0x8018)
222CV_TYPE(LF_DECIMAL, 0x8019)
223CV_TYPE(LF_DATE, 0x801a)
224CV_TYPE(LF_UTF8STRING, 0x801b)
225CV_TYPE(LF_REAL16, 0x801c)
226
227// Padding bytes. These are emitted into alignment bytes in the type stream.
228
229CV_TYPE(LF_PAD0, 0xf0)
230CV_TYPE(LF_PAD1, 0xf1)
231CV_TYPE(LF_PAD2, 0xf2)
232CV_TYPE(LF_PAD3, 0xf3)
233CV_TYPE(LF_PAD4, 0xf4)
234CV_TYPE(LF_PAD5, 0xf5)
235CV_TYPE(LF_PAD6, 0xf6)
236CV_TYPE(LF_PAD7, 0xf7)
237CV_TYPE(LF_PAD8, 0xf8)
238CV_TYPE(LF_PAD9, 0xf9)
239CV_TYPE(LF_PAD10, 0xfa)
240CV_TYPE(LF_PAD11, 0xfb)
241CV_TYPE(LF_PAD12, 0xfc)
242CV_TYPE(LF_PAD13, 0xfd)
243CV_TYPE(LF_PAD14, 0xfe)
244CV_TYPE(LF_PAD15, 0xff)
245
246#undef CV_TYPE
247#undef TYPE_RECORD
248#undef TYPE_RECORD_ALIAS
249#undef MEMBER_RECORD
250#undef MEMBER_RECORD_ALIAS