Bug Summary

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

Annotated Source Code

[?] Use j/k keys for keyboard navigation

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

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

/build/llvm-toolchain-snapshot-6.0~svn321639/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