Bug Summary

File:include/llvm/Support/YAMLTraits.h
Warning:line 811, column 17
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ELFYAML.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-10~svn374877/build-llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-10~svn374877/build-llvm/include -I /build/llvm-toolchain-snapshot-10~svn374877/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-10~svn374877/build-llvm/lib/ObjectYAML -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~svn374877=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2019-10-15-233810-7101-1 -x c++ /build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp

/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp

1//===- ELFYAML.cpp - ELF YAMLIO implementation ----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines classes for handling the YAML representation of ELF.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/ObjectYAML/ELFYAML.h"
14#include "llvm/ADT/MapVector.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/BinaryFormat/ELF.h"
17#include "llvm/Support/Casting.h"
18#include "llvm/Support/ErrorHandling.h"
19#include "llvm/Support/MipsABIFlags.h"
20#include "llvm/Support/YAMLTraits.h"
21#include "llvm/Support/WithColor.h"
22#include <cassert>
23#include <cstdint>
24
25namespace llvm {
26
27ELFYAML::Section::~Section() = default;
28
29namespace yaml {
30
31void ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration(
32 IO &IO, ELFYAML::ELF_ET &Value) {
33#define ECase(X) IO.enumCase(Value, #X, ELF::X)
34 ECase(ET_NONE);
35 ECase(ET_REL);
36 ECase(ET_EXEC);
37 ECase(ET_DYN);
38 ECase(ET_CORE);
39#undef ECase
40 IO.enumFallback<Hex16>(Value);
41}
42
43void ScalarEnumerationTraits<ELFYAML::ELF_PT>::enumeration(
44 IO &IO, ELFYAML::ELF_PT &Value) {
45#define ECase(X) IO.enumCase(Value, #X, ELF::X)
46 ECase(PT_NULL);
47 ECase(PT_LOAD);
48 ECase(PT_DYNAMIC);
49 ECase(PT_INTERP);
50 ECase(PT_NOTE);
51 ECase(PT_SHLIB);
52 ECase(PT_PHDR);
53 ECase(PT_TLS);
54 ECase(PT_GNU_EH_FRAME);
55 ECase(PT_GNU_STACK);
56 ECase(PT_GNU_RELRO);
57#undef ECase
58 IO.enumFallback<Hex32>(Value);
59}
60
61void ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(
62 IO &IO, ELFYAML::ELF_EM &Value) {
63#define ECase(X) IO.enumCase(Value, #X, ELF::X)
64 ECase(EM_NONE);
65 ECase(EM_M32);
66 ECase(EM_SPARC);
67 ECase(EM_386);
68 ECase(EM_68K);
69 ECase(EM_88K);
70 ECase(EM_IAMCU);
71 ECase(EM_860);
72 ECase(EM_MIPS);
73 ECase(EM_S370);
74 ECase(EM_MIPS_RS3_LE);
75 ECase(EM_PARISC);
76 ECase(EM_VPP500);
77 ECase(EM_SPARC32PLUS);
78 ECase(EM_960);
79 ECase(EM_PPC);
80 ECase(EM_PPC64);
81 ECase(EM_S390);
82 ECase(EM_SPU);
83 ECase(EM_V800);
84 ECase(EM_FR20);
85 ECase(EM_RH32);
86 ECase(EM_RCE);
87 ECase(EM_ARM);
88 ECase(EM_ALPHA);
89 ECase(EM_SH);
90 ECase(EM_SPARCV9);
91 ECase(EM_TRICORE);
92 ECase(EM_ARC);
93 ECase(EM_H8_300);
94 ECase(EM_H8_300H);
95 ECase(EM_H8S);
96 ECase(EM_H8_500);
97 ECase(EM_IA_64);
98 ECase(EM_MIPS_X);
99 ECase(EM_COLDFIRE);
100 ECase(EM_68HC12);
101 ECase(EM_MMA);
102 ECase(EM_PCP);
103 ECase(EM_NCPU);
104 ECase(EM_NDR1);
105 ECase(EM_STARCORE);
106 ECase(EM_ME16);
107 ECase(EM_ST100);
108 ECase(EM_TINYJ);
109 ECase(EM_X86_64);
110 ECase(EM_PDSP);
111 ECase(EM_PDP10);
112 ECase(EM_PDP11);
113 ECase(EM_FX66);
114 ECase(EM_ST9PLUS);
115 ECase(EM_ST7);
116 ECase(EM_68HC16);
117 ECase(EM_68HC11);
118 ECase(EM_68HC08);
119 ECase(EM_68HC05);
120 ECase(EM_SVX);
121 ECase(EM_ST19);
122 ECase(EM_VAX);
123 ECase(EM_CRIS);
124 ECase(EM_JAVELIN);
125 ECase(EM_FIREPATH);
126 ECase(EM_ZSP);
127 ECase(EM_MMIX);
128 ECase(EM_HUANY);
129 ECase(EM_PRISM);
130 ECase(EM_AVR);
131 ECase(EM_FR30);
132 ECase(EM_D10V);
133 ECase(EM_D30V);
134 ECase(EM_V850);
135 ECase(EM_M32R);
136 ECase(EM_MN10300);
137 ECase(EM_MN10200);
138 ECase(EM_PJ);
139 ECase(EM_OPENRISC);
140 ECase(EM_ARC_COMPACT);
141 ECase(EM_XTENSA);
142 ECase(EM_VIDEOCORE);
143 ECase(EM_TMM_GPP);
144 ECase(EM_NS32K);
145 ECase(EM_TPC);
146 ECase(EM_SNP1K);
147 ECase(EM_ST200);
148 ECase(EM_IP2K);
149 ECase(EM_MAX);
150 ECase(EM_CR);
151 ECase(EM_F2MC16);
152 ECase(EM_MSP430);
153 ECase(EM_BLACKFIN);
154 ECase(EM_SE_C33);
155 ECase(EM_SEP);
156 ECase(EM_ARCA);
157 ECase(EM_UNICORE);
158 ECase(EM_EXCESS);
159 ECase(EM_DXP);
160 ECase(EM_ALTERA_NIOS2);
161 ECase(EM_CRX);
162 ECase(EM_XGATE);
163 ECase(EM_C166);
164 ECase(EM_M16C);
165 ECase(EM_DSPIC30F);
166 ECase(EM_CE);
167 ECase(EM_M32C);
168 ECase(EM_TSK3000);
169 ECase(EM_RS08);
170 ECase(EM_SHARC);
171 ECase(EM_ECOG2);
172 ECase(EM_SCORE7);
173 ECase(EM_DSP24);
174 ECase(EM_VIDEOCORE3);
175 ECase(EM_LATTICEMICO32);
176 ECase(EM_SE_C17);
177 ECase(EM_TI_C6000);
178 ECase(EM_TI_C2000);
179 ECase(EM_TI_C5500);
180 ECase(EM_MMDSP_PLUS);
181 ECase(EM_CYPRESS_M8C);
182 ECase(EM_R32C);
183 ECase(EM_TRIMEDIA);
184 ECase(EM_HEXAGON);
185 ECase(EM_8051);
186 ECase(EM_STXP7X);
187 ECase(EM_NDS32);
188 ECase(EM_ECOG1);
189 ECase(EM_ECOG1X);
190 ECase(EM_MAXQ30);
191 ECase(EM_XIMO16);
192 ECase(EM_MANIK);
193 ECase(EM_CRAYNV2);
194 ECase(EM_RX);
195 ECase(EM_METAG);
196 ECase(EM_MCST_ELBRUS);
197 ECase(EM_ECOG16);
198 ECase(EM_CR16);
199 ECase(EM_ETPU);
200 ECase(EM_SLE9X);
201 ECase(EM_L10M);
202 ECase(EM_K10M);
203 ECase(EM_AARCH64);
204 ECase(EM_AVR32);
205 ECase(EM_STM8);
206 ECase(EM_TILE64);
207 ECase(EM_TILEPRO);
208 ECase(EM_CUDA);
209 ECase(EM_TILEGX);
210 ECase(EM_CLOUDSHIELD);
211 ECase(EM_COREA_1ST);
212 ECase(EM_COREA_2ND);
213 ECase(EM_ARC_COMPACT2);
214 ECase(EM_OPEN8);
215 ECase(EM_RL78);
216 ECase(EM_VIDEOCORE5);
217 ECase(EM_78KOR);
218 ECase(EM_56800EX);
219 ECase(EM_AMDGPU);
220 ECase(EM_RISCV);
221 ECase(EM_LANAI);
222 ECase(EM_BPF);
223#undef ECase
224 IO.enumFallback<Hex16>(Value);
225}
226
227void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration(
228 IO &IO, ELFYAML::ELF_ELFCLASS &Value) {
229#define ECase(X) IO.enumCase(Value, #X, ELF::X)
230 // Since the semantics of ELFCLASSNONE is "invalid", just don't accept it
231 // here.
232 ECase(ELFCLASS32);
233 ECase(ELFCLASS64);
234#undef ECase
235}
236
237void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration(
238 IO &IO, ELFYAML::ELF_ELFDATA &Value) {
239#define ECase(X) IO.enumCase(Value, #X, ELF::X)
240 // ELFDATANONE is an invalid data encoding, but we accept it because
241 // we want to be able to produce invalid binaries for the tests.
242 ECase(ELFDATANONE);
243 ECase(ELFDATA2LSB);
244 ECase(ELFDATA2MSB);
245#undef ECase
246}
247
248void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
249 IO &IO, ELFYAML::ELF_ELFOSABI &Value) {
250#define ECase(X) IO.enumCase(Value, #X, ELF::X)
251 ECase(ELFOSABI_NONE);
252 ECase(ELFOSABI_HPUX);
253 ECase(ELFOSABI_NETBSD);
254 ECase(ELFOSABI_GNU);
255 ECase(ELFOSABI_HURD);
256 ECase(ELFOSABI_SOLARIS);
257 ECase(ELFOSABI_AIX);
258 ECase(ELFOSABI_IRIX);
259 ECase(ELFOSABI_FREEBSD);
260 ECase(ELFOSABI_TRU64);
261 ECase(ELFOSABI_MODESTO);
262 ECase(ELFOSABI_OPENBSD);
263 ECase(ELFOSABI_OPENVMS);
264 ECase(ELFOSABI_NSK);
265 ECase(ELFOSABI_AROS);
266 ECase(ELFOSABI_FENIXOS);
267 ECase(ELFOSABI_CLOUDABI);
268 ECase(ELFOSABI_AMDGPU_HSA);
269 ECase(ELFOSABI_AMDGPU_PAL);
270 ECase(ELFOSABI_AMDGPU_MESA3D);
271 ECase(ELFOSABI_ARM);
272 ECase(ELFOSABI_C6000_ELFABI);
273 ECase(ELFOSABI_C6000_LINUX);
274 ECase(ELFOSABI_STANDALONE);
275#undef ECase
276}
277
278void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
279 ELFYAML::ELF_EF &Value) {
280 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
281 assert(Object && "The IO context is not initialized")((Object && "The IO context is not initialized") ? static_cast
<void> (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 281, __PRETTY_FUNCTION__))
;
282#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
283#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M)
284 switch (Object->Header.Machine) {
285 case ELF::EM_ARM:
286 BCase(EF_ARM_SOFT_FLOAT);
287 BCase(EF_ARM_VFP_FLOAT);
288 BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK);
289 BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK);
290 BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK);
291 BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK);
292 BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK);
293 BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK);
294 break;
295 case ELF::EM_MIPS:
296 BCase(EF_MIPS_NOREORDER);
297 BCase(EF_MIPS_PIC);
298 BCase(EF_MIPS_CPIC);
299 BCase(EF_MIPS_ABI2);
300 BCase(EF_MIPS_32BITMODE);
301 BCase(EF_MIPS_FP64);
302 BCase(EF_MIPS_NAN2008);
303 BCase(EF_MIPS_MICROMIPS);
304 BCase(EF_MIPS_ARCH_ASE_M16);
305 BCase(EF_MIPS_ARCH_ASE_MDMX);
306 BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI);
307 BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI);
308 BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI);
309 BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI);
310 BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH);
311 BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH);
312 BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH);
313 BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH);
314 BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH);
315 BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH);
316 BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH);
317 BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH);
318 BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH);
319 BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH);
320 BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH);
321 BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH);
322 BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH);
323 BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH);
324 BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH);
325 BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH);
326 BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH);
327 BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH);
328 BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH);
329 BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH);
330 BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH);
331 BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH);
332 BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH);
333 BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH);
334 BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH);
335 BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH);
336 BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH);
337 BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH);
338 BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH);
339 break;
340 case ELF::EM_HEXAGON:
341 BCase(EF_HEXAGON_MACH_V2);
342 BCase(EF_HEXAGON_MACH_V3);
343 BCase(EF_HEXAGON_MACH_V4);
344 BCase(EF_HEXAGON_MACH_V5);
345 BCase(EF_HEXAGON_MACH_V55);
346 BCase(EF_HEXAGON_MACH_V60);
347 BCase(EF_HEXAGON_MACH_V62);
348 BCase(EF_HEXAGON_MACH_V65);
349 BCase(EF_HEXAGON_ISA_V2);
350 BCase(EF_HEXAGON_ISA_V3);
351 BCase(EF_HEXAGON_ISA_V4);
352 BCase(EF_HEXAGON_ISA_V5);
353 BCase(EF_HEXAGON_ISA_V55);
354 BCase(EF_HEXAGON_ISA_V60);
355 BCase(EF_HEXAGON_ISA_V62);
356 BCase(EF_HEXAGON_ISA_V65);
357 break;
358 case ELF::EM_AVR:
359 BCase(EF_AVR_ARCH_AVR1);
360 BCase(EF_AVR_ARCH_AVR2);
361 BCase(EF_AVR_ARCH_AVR25);
362 BCase(EF_AVR_ARCH_AVR3);
363 BCase(EF_AVR_ARCH_AVR31);
364 BCase(EF_AVR_ARCH_AVR35);
365 BCase(EF_AVR_ARCH_AVR4);
366 BCase(EF_AVR_ARCH_AVR51);
367 BCase(EF_AVR_ARCH_AVR6);
368 BCase(EF_AVR_ARCH_AVRTINY);
369 BCase(EF_AVR_ARCH_XMEGA1);
370 BCase(EF_AVR_ARCH_XMEGA2);
371 BCase(EF_AVR_ARCH_XMEGA3);
372 BCase(EF_AVR_ARCH_XMEGA4);
373 BCase(EF_AVR_ARCH_XMEGA5);
374 BCase(EF_AVR_ARCH_XMEGA6);
375 BCase(EF_AVR_ARCH_XMEGA7);
376 break;
377 case ELF::EM_RISCV:
378 BCase(EF_RISCV_RVC);
379 BCaseMask(EF_RISCV_FLOAT_ABI_SOFT, EF_RISCV_FLOAT_ABI);
380 BCaseMask(EF_RISCV_FLOAT_ABI_SINGLE, EF_RISCV_FLOAT_ABI);
381 BCaseMask(EF_RISCV_FLOAT_ABI_DOUBLE, EF_RISCV_FLOAT_ABI);
382 BCaseMask(EF_RISCV_FLOAT_ABI_QUAD, EF_RISCV_FLOAT_ABI);
383 BCase(EF_RISCV_RVE);
384 break;
385 case ELF::EM_AMDGPU:
386 BCaseMask(EF_AMDGPU_MACH_NONE, EF_AMDGPU_MACH);
387 BCaseMask(EF_AMDGPU_MACH_R600_R600, EF_AMDGPU_MACH);
388 BCaseMask(EF_AMDGPU_MACH_R600_R630, EF_AMDGPU_MACH);
389 BCaseMask(EF_AMDGPU_MACH_R600_RS880, EF_AMDGPU_MACH);
390 BCaseMask(EF_AMDGPU_MACH_R600_RV670, EF_AMDGPU_MACH);
391 BCaseMask(EF_AMDGPU_MACH_R600_RV710, EF_AMDGPU_MACH);
392 BCaseMask(EF_AMDGPU_MACH_R600_RV730, EF_AMDGPU_MACH);
393 BCaseMask(EF_AMDGPU_MACH_R600_RV770, EF_AMDGPU_MACH);
394 BCaseMask(EF_AMDGPU_MACH_R600_CEDAR, EF_AMDGPU_MACH);
395 BCaseMask(EF_AMDGPU_MACH_R600_CYPRESS, EF_AMDGPU_MACH);
396 BCaseMask(EF_AMDGPU_MACH_R600_JUNIPER, EF_AMDGPU_MACH);
397 BCaseMask(EF_AMDGPU_MACH_R600_REDWOOD, EF_AMDGPU_MACH);
398 BCaseMask(EF_AMDGPU_MACH_R600_SUMO, EF_AMDGPU_MACH);
399 BCaseMask(EF_AMDGPU_MACH_R600_BARTS, EF_AMDGPU_MACH);
400 BCaseMask(EF_AMDGPU_MACH_R600_CAICOS, EF_AMDGPU_MACH);
401 BCaseMask(EF_AMDGPU_MACH_R600_CAYMAN, EF_AMDGPU_MACH);
402 BCaseMask(EF_AMDGPU_MACH_R600_TURKS, EF_AMDGPU_MACH);
403 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX600, EF_AMDGPU_MACH);
404 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX601, EF_AMDGPU_MACH);
405 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX700, EF_AMDGPU_MACH);
406 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX701, EF_AMDGPU_MACH);
407 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX702, EF_AMDGPU_MACH);
408 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX703, EF_AMDGPU_MACH);
409 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX704, EF_AMDGPU_MACH);
410 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX801, EF_AMDGPU_MACH);
411 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX802, EF_AMDGPU_MACH);
412 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX803, EF_AMDGPU_MACH);
413 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX810, EF_AMDGPU_MACH);
414 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX900, EF_AMDGPU_MACH);
415 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX902, EF_AMDGPU_MACH);
416 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX904, EF_AMDGPU_MACH);
417 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX906, EF_AMDGPU_MACH);
418 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX908, EF_AMDGPU_MACH);
419 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX909, EF_AMDGPU_MACH);
420 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1010, EF_AMDGPU_MACH);
421 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1011, EF_AMDGPU_MACH);
422 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1012, EF_AMDGPU_MACH);
423 BCase(EF_AMDGPU_XNACK);
424 BCase(EF_AMDGPU_SRAM_ECC);
425 break;
426 case ELF::EM_X86_64:
427 break;
428 default:
429 llvm_unreachable("Unsupported architecture")::llvm::llvm_unreachable_internal("Unsupported architecture",
"/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 429)
;
430 }
431#undef BCase
432#undef BCaseMask
433}
434
435void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
436 IO &IO, ELFYAML::ELF_SHT &Value) {
437 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
438 assert(Object && "The IO context is not initialized")((Object && "The IO context is not initialized") ? static_cast
<void> (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 438, __PRETTY_FUNCTION__))
;
12
Assuming 'Object' is non-null
13
'?' condition is true
439#define ECase(X) IO.enumCase(Value, #X, ELF::X)
440 ECase(SHT_NULL);
14
Calling 'IO::enumCase'
19
Returning from 'IO::enumCase'
441 ECase(SHT_PROGBITS);
20
Calling 'IO::enumCase'
25
Returning from 'IO::enumCase'
442 ECase(SHT_SYMTAB);
26
Calling 'IO::enumCase'
31
Returning from 'IO::enumCase'
443 // FIXME: Issue a diagnostic with this information.
444 ECase(SHT_STRTAB);
32
Calling 'IO::enumCase'
37
Returning from 'IO::enumCase'
445 ECase(SHT_RELA);
38
Calling 'IO::enumCase'
43
Returning from 'IO::enumCase'
446 ECase(SHT_HASH);
44
Calling 'IO::enumCase'
49
Returning from 'IO::enumCase'
447 ECase(SHT_DYNAMIC);
50
Calling 'IO::enumCase'
55
Returning from 'IO::enumCase'
448 ECase(SHT_NOTE);
56
Calling 'IO::enumCase'
61
Returning from 'IO::enumCase'
449 ECase(SHT_NOBITS);
62
Calling 'IO::enumCase'
67
Returning from 'IO::enumCase'
450 ECase(SHT_REL);
68
Calling 'IO::enumCase'
73
Returning from 'IO::enumCase'
451 ECase(SHT_SHLIB);
74
Calling 'IO::enumCase'
79
Returning from 'IO::enumCase'
452 ECase(SHT_DYNSYM);
80
Calling 'IO::enumCase'
85
Returning from 'IO::enumCase'
453 ECase(SHT_INIT_ARRAY);
86
Calling 'IO::enumCase'
91
Returning from 'IO::enumCase'
454 ECase(SHT_FINI_ARRAY);
92
Calling 'IO::enumCase'
97
Returning from 'IO::enumCase'
455 ECase(SHT_PREINIT_ARRAY);
98
Calling 'IO::enumCase'
103
Returning from 'IO::enumCase'
456 ECase(SHT_GROUP);
104
Calling 'IO::enumCase'
109
Returning from 'IO::enumCase'
457 ECase(SHT_SYMTAB_SHNDX);
110
Calling 'IO::enumCase'
115
Returning from 'IO::enumCase'
458 ECase(SHT_RELR);
116
Calling 'IO::enumCase'
121
Returning from 'IO::enumCase'
459 ECase(SHT_ANDROID_REL);
122
Calling 'IO::enumCase'
127
Returning from 'IO::enumCase'
460 ECase(SHT_ANDROID_RELA);
128
Calling 'IO::enumCase'
133
Returning from 'IO::enumCase'
461 ECase(SHT_ANDROID_RELR);
134
Calling 'IO::enumCase'
139
Returning from 'IO::enumCase'
462 ECase(SHT_LLVM_ODRTAB);
140
Calling 'IO::enumCase'
145
Returning from 'IO::enumCase'
463 ECase(SHT_LLVM_LINKER_OPTIONS);
146
Calling 'IO::enumCase'
151
Returning from 'IO::enumCase'
464 ECase(SHT_LLVM_CALL_GRAPH_PROFILE);
152
Calling 'IO::enumCase'
157
Returning from 'IO::enumCase'
465 ECase(SHT_LLVM_ADDRSIG);
158
Calling 'IO::enumCase'
163
Returning from 'IO::enumCase'
466 ECase(SHT_LLVM_DEPENDENT_LIBRARIES);
164
Calling 'IO::enumCase'
169
Returning from 'IO::enumCase'
467 ECase(SHT_LLVM_SYMPART);
170
Calling 'IO::enumCase'
175
Returning from 'IO::enumCase'
468 ECase(SHT_LLVM_PART_EHDR);
176
Calling 'IO::enumCase'
181
Returning from 'IO::enumCase'
469 ECase(SHT_LLVM_PART_PHDR);
182
Calling 'IO::enumCase'
187
Returning from 'IO::enumCase'
470 ECase(SHT_GNU_ATTRIBUTES);
188
Calling 'IO::enumCase'
193
Returning from 'IO::enumCase'
471 ECase(SHT_GNU_HASH);
194
Calling 'IO::enumCase'
199
Returning from 'IO::enumCase'
472 ECase(SHT_GNU_verdef);
200
Calling 'IO::enumCase'
205
Returning from 'IO::enumCase'
473 ECase(SHT_GNU_verneed);
206
Calling 'IO::enumCase'
211
Returning from 'IO::enumCase'
474 ECase(SHT_GNU_versym);
212
Calling 'IO::enumCase'
217
Returning from 'IO::enumCase'
475 switch (Object->Header.Machine) {
218
Control jumps to the 'default' case at line 495
476 case ELF::EM_ARM:
477 ECase(SHT_ARM_EXIDX);
478 ECase(SHT_ARM_PREEMPTMAP);
479 ECase(SHT_ARM_ATTRIBUTES);
480 ECase(SHT_ARM_DEBUGOVERLAY);
481 ECase(SHT_ARM_OVERLAYSECTION);
482 break;
483 case ELF::EM_HEXAGON:
484 ECase(SHT_HEX_ORDERED);
485 break;
486 case ELF::EM_X86_64:
487 ECase(SHT_X86_64_UNWIND);
488 break;
489 case ELF::EM_MIPS:
490 ECase(SHT_MIPS_REGINFO);
491 ECase(SHT_MIPS_OPTIONS);
492 ECase(SHT_MIPS_DWARF);
493 ECase(SHT_MIPS_ABIFLAGS);
494 break;
495 default:
496 // Nothing to do.
497 break;
219
Execution continues on line 500
498 }
499#undef ECase
500 IO.enumFallback<Hex32>(Value);
220
Calling 'IO::enumFallback'
501}
502
503void ScalarBitSetTraits<ELFYAML::ELF_PF>::bitset(IO &IO,
504 ELFYAML::ELF_PF &Value) {
505#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
506 BCase(PF_X);
507 BCase(PF_W);
508 BCase(PF_R);
509}
510
511void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
512 ELFYAML::ELF_SHF &Value) {
513 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
514#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
515 BCase(SHF_WRITE);
516 BCase(SHF_ALLOC);
517 BCase(SHF_EXCLUDE);
518 BCase(SHF_EXECINSTR);
519 BCase(SHF_MERGE);
520 BCase(SHF_STRINGS);
521 BCase(SHF_INFO_LINK);
522 BCase(SHF_LINK_ORDER);
523 BCase(SHF_OS_NONCONFORMING);
524 BCase(SHF_GROUP);
525 BCase(SHF_TLS);
526 BCase(SHF_COMPRESSED);
527 switch (Object->Header.Machine) {
528 case ELF::EM_ARM:
529 BCase(SHF_ARM_PURECODE);
530 break;
531 case ELF::EM_HEXAGON:
532 BCase(SHF_HEX_GPREL);
533 break;
534 case ELF::EM_MIPS:
535 BCase(SHF_MIPS_NODUPES);
536 BCase(SHF_MIPS_NAMES);
537 BCase(SHF_MIPS_LOCAL);
538 BCase(SHF_MIPS_NOSTRIP);
539 BCase(SHF_MIPS_GPREL);
540 BCase(SHF_MIPS_MERGE);
541 BCase(SHF_MIPS_ADDR);
542 BCase(SHF_MIPS_STRING);
543 break;
544 case ELF::EM_X86_64:
545 BCase(SHF_X86_64_LARGE);
546 break;
547 default:
548 // Nothing to do.
549 break;
550 }
551#undef BCase
552}
553
554void ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration(
555 IO &IO, ELFYAML::ELF_SHN &Value) {
556#define ECase(X) IO.enumCase(Value, #X, ELF::X)
557 ECase(SHN_UNDEF);
558 ECase(SHN_LORESERVE);
559 ECase(SHN_LOPROC);
560 ECase(SHN_HIPROC);
561 ECase(SHN_LOOS);
562 ECase(SHN_HIOS);
563 ECase(SHN_ABS);
564 ECase(SHN_COMMON);
565 ECase(SHN_XINDEX);
566 ECase(SHN_HIRESERVE);
567 ECase(SHN_AMDGPU_LDS);
568 ECase(SHN_HEXAGON_SCOMMON);
569 ECase(SHN_HEXAGON_SCOMMON_1);
570 ECase(SHN_HEXAGON_SCOMMON_2);
571 ECase(SHN_HEXAGON_SCOMMON_4);
572 ECase(SHN_HEXAGON_SCOMMON_8);
573#undef ECase
574 IO.enumFallback<Hex16>(Value);
575}
576
577void ScalarEnumerationTraits<ELFYAML::ELF_STB>::enumeration(
578 IO &IO, ELFYAML::ELF_STB &Value) {
579#define ECase(X) IO.enumCase(Value, #X, ELF::X)
580 ECase(STB_LOCAL);
581 ECase(STB_GLOBAL);
582 ECase(STB_WEAK);
583 ECase(STB_GNU_UNIQUE);
584#undef ECase
585 IO.enumFallback<Hex8>(Value);
586}
587
588void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
589 IO &IO, ELFYAML::ELF_STT &Value) {
590#define ECase(X) IO.enumCase(Value, #X, ELF::X)
591 ECase(STT_NOTYPE);
592 ECase(STT_OBJECT);
593 ECase(STT_FUNC);
594 ECase(STT_SECTION);
595 ECase(STT_FILE);
596 ECase(STT_COMMON);
597 ECase(STT_TLS);
598 ECase(STT_GNU_IFUNC);
599#undef ECase
600 IO.enumFallback<Hex8>(Value);
601}
602
603
604void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration(
605 IO &IO, ELFYAML::ELF_RSS &Value) {
606#define ECase(X) IO.enumCase(Value, #X, ELF::X)
607 ECase(RSS_UNDEF);
608 ECase(RSS_GP);
609 ECase(RSS_GP0);
610 ECase(RSS_LOC);
611#undef ECase
612}
613
614void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
615 IO &IO, ELFYAML::ELF_REL &Value) {
616 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
617 assert(Object && "The IO context is not initialized")((Object && "The IO context is not initialized") ? static_cast
<void> (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 617, __PRETTY_FUNCTION__))
;
618#define ELF_RELOC(X, Y) IO.enumCase(Value, #X, ELF::X);
619 switch (Object->Header.Machine) {
620 case ELF::EM_X86_64:
621#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
622 break;
623 case ELF::EM_MIPS:
624#include "llvm/BinaryFormat/ELFRelocs/Mips.def"
625 break;
626 case ELF::EM_HEXAGON:
627#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
628 break;
629 case ELF::EM_386:
630 case ELF::EM_IAMCU:
631#include "llvm/BinaryFormat/ELFRelocs/i386.def"
632 break;
633 case ELF::EM_AARCH64:
634#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
635 break;
636 case ELF::EM_ARM:
637#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
638 break;
639 case ELF::EM_ARC:
640#include "llvm/BinaryFormat/ELFRelocs/ARC.def"
641 break;
642 case ELF::EM_RISCV:
643#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
644 break;
645 case ELF::EM_LANAI:
646#include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
647 break;
648 case ELF::EM_AMDGPU:
649#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
650 break;
651 case ELF::EM_BPF:
652#include "llvm/BinaryFormat/ELFRelocs/BPF.def"
653 break;
654 case ELF::EM_PPC64:
655#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
656 break;
657 default:
658 // Nothing to do.
659 break;
660 }
661#undef ELF_RELOC
662 IO.enumFallback<Hex32>(Value);
663}
664
665void ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG>::enumeration(
666 IO &IO, ELFYAML::ELF_DYNTAG &Value) {
667 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
668 assert(Object && "The IO context is not initialized")((Object && "The IO context is not initialized") ? static_cast
<void> (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 668, __PRETTY_FUNCTION__))
;
669
670// Disable architecture specific tags by default. We might enable them below.
671#define AARCH64_DYNAMIC_TAG(name, value)
672#define MIPS_DYNAMIC_TAG(name, value)
673#define HEXAGON_DYNAMIC_TAG(name, value)
674#define PPC_DYNAMIC_TAG(name, value)
675#define PPC64_DYNAMIC_TAG(name, value)
676// Ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
677#define DYNAMIC_TAG_MARKER(name, value)
678
679#define STRINGIFY(X) (#X)
680#define DYNAMIC_TAG(X, Y) IO.enumCase(Value, STRINGIFY(DT_##X), ELF::DT_##X);
681 switch (Object->Header.Machine) {
682 case ELF::EM_AARCH64:
683#undef AARCH64_DYNAMIC_TAG
684#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
685#include "llvm/BinaryFormat/DynamicTags.def"
686#undef AARCH64_DYNAMIC_TAG
687#define AARCH64_DYNAMIC_TAG(name, value)
688 break;
689 case ELF::EM_MIPS:
690#undef MIPS_DYNAMIC_TAG
691#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
692#include "llvm/BinaryFormat/DynamicTags.def"
693#undef MIPS_DYNAMIC_TAG
694#define MIPS_DYNAMIC_TAG(name, value)
695 break;
696 case ELF::EM_HEXAGON:
697#undef HEXAGON_DYNAMIC_TAG
698#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
699#include "llvm/BinaryFormat/DynamicTags.def"
700#undef HEXAGON_DYNAMIC_TAG
701#define HEXAGON_DYNAMIC_TAG(name, value)
702 break;
703 case ELF::EM_PPC:
704#undef PPC_DYNAMIC_TAG
705#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
706#include "llvm/BinaryFormat/DynamicTags.def"
707#undef PPC_DYNAMIC_TAG
708#define PPC_DYNAMIC_TAG(name, value)
709 break;
710 case ELF::EM_PPC64:
711#undef PPC64_DYNAMIC_TAG
712#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
713#include "llvm/BinaryFormat/DynamicTags.def"
714#undef PPC64_DYNAMIC_TAG
715#define PPC64_DYNAMIC_TAG(name, value)
716 break;
717 default:
718#include "llvm/BinaryFormat/DynamicTags.def"
719 break;
720 }
721#undef AARCH64_DYNAMIC_TAG
722#undef MIPS_DYNAMIC_TAG
723#undef HEXAGON_DYNAMIC_TAG
724#undef PPC_DYNAMIC_TAG
725#undef PPC64_DYNAMIC_TAG
726#undef DYNAMIC_TAG_MARKER
727#undef STRINGIFY
728#undef DYNAMIC_TAG
729
730 IO.enumFallback<Hex64>(Value);
731}
732
733void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration(
734 IO &IO, ELFYAML::MIPS_AFL_REG &Value) {
735#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X)
736 ECase(REG_NONE);
737 ECase(REG_32);
738 ECase(REG_64);
739 ECase(REG_128);
740#undef ECase
741}
742
743void ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP>::enumeration(
744 IO &IO, ELFYAML::MIPS_ABI_FP &Value) {
745#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X)
746 ECase(FP_ANY);
747 ECase(FP_DOUBLE);
748 ECase(FP_SINGLE);
749 ECase(FP_SOFT);
750 ECase(FP_OLD_64);
751 ECase(FP_XX);
752 ECase(FP_64);
753 ECase(FP_64A);
754#undef ECase
755}
756
757void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT>::enumeration(
758 IO &IO, ELFYAML::MIPS_AFL_EXT &Value) {
759#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X)
760 ECase(EXT_NONE);
761 ECase(EXT_XLR);
762 ECase(EXT_OCTEON2);
763 ECase(EXT_OCTEONP);
764 ECase(EXT_LOONGSON_3A);
765 ECase(EXT_OCTEON);
766 ECase(EXT_5900);
767 ECase(EXT_4650);
768 ECase(EXT_4010);
769 ECase(EXT_4100);
770 ECase(EXT_3900);
771 ECase(EXT_10000);
772 ECase(EXT_SB1);
773 ECase(EXT_4111);
774 ECase(EXT_4120);
775 ECase(EXT_5400);
776 ECase(EXT_5500);
777 ECase(EXT_LOONGSON_2E);
778 ECase(EXT_LOONGSON_2F);
779 ECase(EXT_OCTEON3);
780#undef ECase
781}
782
783void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration(
784 IO &IO, ELFYAML::MIPS_ISA &Value) {
785 IO.enumCase(Value, "MIPS1", 1);
786 IO.enumCase(Value, "MIPS2", 2);
787 IO.enumCase(Value, "MIPS3", 3);
788 IO.enumCase(Value, "MIPS4", 4);
789 IO.enumCase(Value, "MIPS5", 5);
790 IO.enumCase(Value, "MIPS32", 32);
791 IO.enumCase(Value, "MIPS64", 64);
792}
793
794void ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE>::bitset(
795 IO &IO, ELFYAML::MIPS_AFL_ASE &Value) {
796#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X)
797 BCase(DSP);
798 BCase(DSPR2);
799 BCase(EVA);
800 BCase(MCU);
801 BCase(MDMX);
802 BCase(MIPS3D);
803 BCase(MT);
804 BCase(SMARTMIPS);
805 BCase(VIRT);
806 BCase(MSA);
807 BCase(MIPS16);
808 BCase(MICROMIPS);
809 BCase(XPA);
810#undef BCase
811}
812
813void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset(
814 IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value) {
815#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X)
816 BCase(ODDSPREG);
817#undef BCase
818}
819
820void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
821 ELFYAML::FileHeader &FileHdr) {
822 IO.mapRequired("Class", FileHdr.Class);
823 IO.mapRequired("Data", FileHdr.Data);
824 IO.mapOptional("OSABI", FileHdr.OSABI, ELFYAML::ELF_ELFOSABI(0));
825 IO.mapOptional("ABIVersion", FileHdr.ABIVersion, Hex8(0));
826 IO.mapRequired("Type", FileHdr.Type);
827 IO.mapRequired("Machine", FileHdr.Machine);
828 IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
829 IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
830
831 IO.mapOptional("SHEntSize", FileHdr.SHEntSize);
832 IO.mapOptional("SHOff", FileHdr.SHOff);
833 IO.mapOptional("SHNum", FileHdr.SHNum);
834 IO.mapOptional("SHStrNdx", FileHdr.SHStrNdx);
835}
836
837void MappingTraits<ELFYAML::ProgramHeader>::mapping(
838 IO &IO, ELFYAML::ProgramHeader &Phdr) {
839 IO.mapRequired("Type", Phdr.Type);
840 IO.mapOptional("Flags", Phdr.Flags, ELFYAML::ELF_PF(0));
841 IO.mapOptional("Sections", Phdr.Sections);
842 IO.mapOptional("VAddr", Phdr.VAddr, Hex64(0));
843 IO.mapOptional("PAddr", Phdr.PAddr, Hex64(0));
844 IO.mapOptional("Align", Phdr.Align);
845 IO.mapOptional("FileSize", Phdr.FileSize);
846 IO.mapOptional("MemSize", Phdr.MemSize);
847 IO.mapOptional("Offset", Phdr.Offset);
848}
849
850LLVM_YAML_STRONG_TYPEDEF(StringRef, StOtherPiece)struct StOtherPiece { StOtherPiece() = default; StOtherPiece(
const StringRef v) : value(v) {} StOtherPiece(const StOtherPiece
&v) = default; StOtherPiece &operator=(const StOtherPiece
&rhs) = default; StOtherPiece &operator=(const StringRef
&rhs) { value = rhs; return *this; } operator const StringRef
& () const { return value; } bool operator==(const StOtherPiece
&rhs) const { return value == rhs.value; } bool operator
==(const StringRef &rhs) const { return value == rhs; } bool
operator<(const StOtherPiece &rhs) const { return value
< rhs.value; } StringRef value; using BaseType = StringRef
; };
851
852template <> struct ScalarTraits<StOtherPiece> {
853 static void output(const StOtherPiece &Val, void *, raw_ostream &Out) {
854 Out << Val;
855 }
856 static StringRef input(StringRef Scalar, void *, StOtherPiece &Val) {
857 Val = Scalar;
858 return {};
859 }
860 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
861};
862template <> struct SequenceElementTraits<StOtherPiece> {
863 static const bool flow = true;
864};
865
866namespace {
867
868struct NormalizedOther {
869 NormalizedOther(IO &IO) : YamlIO(IO) {}
870 NormalizedOther(IO &IO, Optional<uint8_t> Original) : YamlIO(IO) {
871 assert(Original && "This constructor is only used for outputting YAML and "((Original && "This constructor is only used for outputting YAML and "
"assumes a non-empty Original") ? static_cast<void> (0
) : __assert_fail ("Original && \"This constructor is only used for outputting YAML and \" \"assumes a non-empty Original\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 872, __PRETTY_FUNCTION__))
872 "assumes a non-empty Original")((Original && "This constructor is only used for outputting YAML and "
"assumes a non-empty Original") ? static_cast<void> (0
) : __assert_fail ("Original && \"This constructor is only used for outputting YAML and \" \"assumes a non-empty Original\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 872, __PRETTY_FUNCTION__))
;
873 std::vector<StOtherPiece> Ret;
874 const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext());
875 for (std::pair<StringRef, uint8_t> &P :
876 getFlags(Object->Header.Machine).takeVector()) {
877 uint8_t FlagValue = P.second;
878 if ((*Original & FlagValue) != FlagValue)
879 continue;
880 *Original &= ~FlagValue;
881 Ret.push_back({P.first});
882 }
883
884 if (*Original != 0) {
885 UnknownFlagsHolder = std::to_string(*Original);
886 Ret.push_back({UnknownFlagsHolder});
887 }
888
889 if (!Ret.empty())
890 Other = std::move(Ret);
891 }
892
893 uint8_t toValue(StringRef Name) {
894 const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext());
895 MapVector<StringRef, uint8_t> Flags = getFlags(Object->Header.Machine);
896
897 auto It = Flags.find(Name);
898 if (It != Flags.end())
899 return It->second;
900
901 uint8_t Val;
902 if (to_integer(Name, Val))
903 return Val;
904
905 YamlIO.setError("an unknown value is used for symbol's 'Other' field: " +
906 Name);
907 return 0;
908 }
909
910 Optional<uint8_t> denormalize(IO &) {
911 if (!Other)
912 return None;
913 uint8_t Ret = 0;
914 for (StOtherPiece &Val : *Other)
915 Ret |= toValue(Val);
916 return Ret;
917 }
918
919 // st_other field is used to encode symbol visibility and platform-dependent
920 // flags and values. This method returns a name to value map that is used for
921 // parsing and encoding this field.
922 MapVector<StringRef, uint8_t> getFlags(unsigned EMachine) {
923 MapVector<StringRef, uint8_t> Map;
924 // STV_* values are just enumeration values. We add them in a reversed order
925 // because when we convert the st_other to named constants when printing
926 // YAML we want to use a maximum number of bits on each step:
927 // when we have st_other == 3, we want to print it as STV_PROTECTED (3), but
928 // not as STV_HIDDEN (2) + STV_INTERNAL (1).
929 Map["STV_PROTECTED"] = ELF::STV_PROTECTED;
930 Map["STV_HIDDEN"] = ELF::STV_HIDDEN;
931 Map["STV_INTERNAL"] = ELF::STV_INTERNAL;
932 // STV_DEFAULT is used to represent the default visibility and has a value
933 // 0. We want to be able to read it from YAML documents, but there is no
934 // reason to print it.
935 if (!YamlIO.outputting())
936 Map["STV_DEFAULT"] = ELF::STV_DEFAULT;
937
938 // MIPS is not consistent. All of the STO_MIPS_* values are bit flags,
939 // except STO_MIPS_MIPS16 which overlaps them. It should be checked and
940 // consumed first when we print the output, because we do not want to print
941 // any other flags that have the same bits instead.
942 if (EMachine == ELF::EM_MIPS) {
943 Map["STO_MIPS_MIPS16"] = ELF::STO_MIPS_MIPS16;
944 Map["STO_MIPS_MICROMIPS"] = ELF::STO_MIPS_MICROMIPS;
945 Map["STO_MIPS_PIC"] = ELF::STO_MIPS_PIC;
946 Map["STO_MIPS_PLT"] = ELF::STO_MIPS_PLT;
947 Map["STO_MIPS_OPTIONAL"] = ELF::STO_MIPS_OPTIONAL;
948 }
949 return Map;
950 }
951
952 IO &YamlIO;
953 Optional<std::vector<StOtherPiece>> Other;
954 std::string UnknownFlagsHolder;
955};
956
957} // end anonymous namespace
958
959void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
960 IO.mapOptional("Name", Symbol.Name, StringRef());
961 IO.mapOptional("NameIndex", Symbol.NameIndex);
962 IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
963 IO.mapOptional("Section", Symbol.Section, StringRef());
964 IO.mapOptional("Index", Symbol.Index);
965 IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0));
966 IO.mapOptional("Value", Symbol.Value, Hex64(0));
967 IO.mapOptional("Size", Symbol.Size, Hex64(0));
968
969 // Symbol's Other field is a bit special. It is usually a field that
970 // represents st_other and holds the symbol visibility. However, on some
971 // platforms, it can contain bit fields and regular values, or even sometimes a
972 // crazy mix of them (see comments for NormalizedOther). Because of this, we
973 // need special handling.
974 MappingNormalization<NormalizedOther, Optional<uint8_t>> Keys(IO,
975 Symbol.Other);
976 IO.mapOptional("Other", Keys->Other);
977}
978
979StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
980 ELFYAML::Symbol &Symbol) {
981 if (Symbol.Index && Symbol.Section.data())
982 return "Index and Section cannot both be specified for Symbol";
983 if (Symbol.NameIndex && !Symbol.Name.empty())
984 return "Name and NameIndex cannot both be specified for Symbol";
985 return StringRef();
986}
987
988static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
989 IO.mapOptional("Name", Section.Name, StringRef());
990 IO.mapRequired("Type", Section.Type);
991 IO.mapOptional("Flags", Section.Flags);
992 IO.mapOptional("Address", Section.Address, Hex64(0));
993 IO.mapOptional("Link", Section.Link, StringRef());
994 IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
995 IO.mapOptional("EntSize", Section.EntSize);
996
997 // obj2yaml does not dump these fields. They are expected to be empty when we
998 // are producing YAML, because yaml2obj sets appropriate values for them
999 // automatically when they are not explicitly defined.
1000 assert(!IO.outputting() ||((!IO.outputting() || (!Section.ShOffset.hasValue() &&
!Section.ShSize.hasValue())) ? static_cast<void> (0) :
__assert_fail ("!IO.outputting() || (!Section.ShOffset.hasValue() && !Section.ShSize.hasValue())"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 1001, __PRETTY_FUNCTION__))
1001 (!Section.ShOffset.hasValue() && !Section.ShSize.hasValue()))((!IO.outputting() || (!Section.ShOffset.hasValue() &&
!Section.ShSize.hasValue())) ? static_cast<void> (0) :
__assert_fail ("!IO.outputting() || (!Section.ShOffset.hasValue() && !Section.ShSize.hasValue())"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 1001, __PRETTY_FUNCTION__))
;
1002 IO.mapOptional("ShName", Section.ShName);
1003 IO.mapOptional("ShOffset", Section.ShOffset);
1004 IO.mapOptional("ShSize", Section.ShSize);
1005}
1006
1007static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
1008 commonSectionMapping(IO, Section);
1009 IO.mapOptional("Entries", Section.Entries);
1010 IO.mapOptional("Content", Section.Content);
1011}
1012
1013static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
1014 commonSectionMapping(IO, Section);
1015 IO.mapOptional("Content", Section.Content);
1016 IO.mapOptional("Size", Section.Size);
1017 IO.mapOptional("Info", Section.Info);
1018}
1019
1020static void sectionMapping(IO &IO, ELFYAML::StackSizesSection &Section) {
1021 commonSectionMapping(IO, Section);
1022 IO.mapOptional("Content", Section.Content);
1023 IO.mapOptional("Size", Section.Size);
1024 IO.mapOptional("Entries", Section.Entries);
1025}
1026
1027static void sectionMapping(IO &IO, ELFYAML::HashSection &Section) {
1028 commonSectionMapping(IO, Section);
1029 IO.mapOptional("Content", Section.Content);
1030 IO.mapOptional("Bucket", Section.Bucket);
1031 IO.mapOptional("Chain", Section.Chain);
1032 IO.mapOptional("Size", Section.Size);
1033}
1034
1035static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
1036 commonSectionMapping(IO, Section);
1037 IO.mapOptional("Size", Section.Size, Hex64(0));
1038}
1039
1040static void sectionMapping(IO &IO, ELFYAML::VerdefSection &Section) {
1041 commonSectionMapping(IO, Section);
1042 IO.mapRequired("Info", Section.Info);
1043 IO.mapRequired("Entries", Section.Entries);
1044}
1045
1046static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
1047 commonSectionMapping(IO, Section);
1048 IO.mapRequired("Entries", Section.Entries);
1049}
1050
1051static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) {
1052 commonSectionMapping(IO, Section);
1053 IO.mapRequired("Info", Section.Info);
1054 IO.mapRequired("Dependencies", Section.VerneedV);
1055}
1056
1057static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
1058 commonSectionMapping(IO, Section);
1059 IO.mapOptional("Info", Section.RelocatableSec, StringRef());
1060 IO.mapOptional("Relocations", Section.Relocations);
1061}
1062
1063static void groupSectionMapping(IO &IO, ELFYAML::Group &Group) {
1064 commonSectionMapping(IO, Group);
1065 IO.mapOptional("Info", Group.Signature, StringRef());
1066 IO.mapRequired("Members", Group.Members);
1067}
1068
1069static void sectionMapping(IO &IO, ELFYAML::SymtabShndxSection &Section) {
1070 commonSectionMapping(IO, Section);
1071 IO.mapRequired("Entries", Section.Entries);
1072}
1073
1074static void sectionMapping(IO &IO, ELFYAML::AddrsigSection &Section) {
1075 commonSectionMapping(IO, Section);
1076 IO.mapOptional("Content", Section.Content);
1077 IO.mapOptional("Size", Section.Size);
1078 IO.mapOptional("Symbols", Section.Symbols);
1079}
1080
1081void MappingTraits<ELFYAML::SectionOrType>::mapping(
1082 IO &IO, ELFYAML::SectionOrType &sectionOrType) {
1083 IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
1084}
1085
1086void MappingTraits<ELFYAML::SectionName>::mapping(
1087 IO &IO, ELFYAML::SectionName &sectionName) {
1088 IO.mapRequired("Section", sectionName.Section);
1089}
1090
1091static void sectionMapping(IO &IO, ELFYAML::MipsABIFlags &Section) {
1092 commonSectionMapping(IO, Section);
1093 IO.mapOptional("Version", Section.Version, Hex16(0));
1094 IO.mapRequired("ISA", Section.ISALevel);
1095 IO.mapOptional("ISARevision", Section.ISARevision, Hex8(0));
1096 IO.mapOptional("ISAExtension", Section.ISAExtension,
1097 ELFYAML::MIPS_AFL_EXT(Mips::AFL_EXT_NONE));
1098 IO.mapOptional("ASEs", Section.ASEs, ELFYAML::MIPS_AFL_ASE(0));
1099 IO.mapOptional("FpABI", Section.FpABI,
1100 ELFYAML::MIPS_ABI_FP(Mips::Val_GNU_MIPS_ABI_FP_ANY));
1101 IO.mapOptional("GPRSize", Section.GPRSize,
1102 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1103 IO.mapOptional("CPR1Size", Section.CPR1Size,
1104 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1105 IO.mapOptional("CPR2Size", Section.CPR2Size,
1106 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1107 IO.mapOptional("Flags1", Section.Flags1, ELFYAML::MIPS_AFL_FLAGS1(0));
1108 IO.mapOptional("Flags2", Section.Flags2, Hex32(0));
1109}
1110
1111void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
1112 IO &IO, std::unique_ptr<ELFYAML::Section> &Section) {
1113 ELFYAML::ELF_SHT sectionType;
1
Calling defaulted default constructor for 'ELF_SHT'
3
Returning from default constructor for 'ELF_SHT'
1114 if (IO.outputting())
4
Assuming the condition is false
5
Taking false branch
1115 sectionType = Section->Type;
1116 else
1117 IO.mapRequired("Type", sectionType);
6
Calling 'IO::mapRequired'
1118
1119 switch (sectionType) {
1120 case ELF::SHT_DYNAMIC:
1121 if (!IO.outputting())
1122 Section.reset(new ELFYAML::DynamicSection());
1123 sectionMapping(IO, *cast<ELFYAML::DynamicSection>(Section.get()));
1124 break;
1125 case ELF::SHT_REL:
1126 case ELF::SHT_RELA:
1127 if (!IO.outputting())
1128 Section.reset(new ELFYAML::RelocationSection());
1129 sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
1130 break;
1131 case ELF::SHT_GROUP:
1132 if (!IO.outputting())
1133 Section.reset(new ELFYAML::Group());
1134 groupSectionMapping(IO, *cast<ELFYAML::Group>(Section.get()));
1135 break;
1136 case ELF::SHT_NOBITS:
1137 if (!IO.outputting())
1138 Section.reset(new ELFYAML::NoBitsSection());
1139 sectionMapping(IO, *cast<ELFYAML::NoBitsSection>(Section.get()));
1140 break;
1141 case ELF::SHT_HASH:
1142 if (!IO.outputting())
1143 Section.reset(new ELFYAML::HashSection());
1144 sectionMapping(IO, *cast<ELFYAML::HashSection>(Section.get()));
1145 break;
1146 case ELF::SHT_MIPS_ABIFLAGS:
1147 if (!IO.outputting())
1148 Section.reset(new ELFYAML::MipsABIFlags());
1149 sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
1150 break;
1151 case ELF::SHT_GNU_verdef:
1152 if (!IO.outputting())
1153 Section.reset(new ELFYAML::VerdefSection());
1154 sectionMapping(IO, *cast<ELFYAML::VerdefSection>(Section.get()));
1155 break;
1156 case ELF::SHT_GNU_versym:
1157 if (!IO.outputting())
1158 Section.reset(new ELFYAML::SymverSection());
1159 sectionMapping(IO, *cast<ELFYAML::SymverSection>(Section.get()));
1160 break;
1161 case ELF::SHT_GNU_verneed:
1162 if (!IO.outputting())
1163 Section.reset(new ELFYAML::VerneedSection());
1164 sectionMapping(IO, *cast<ELFYAML::VerneedSection>(Section.get()));
1165 break;
1166 case ELF::SHT_SYMTAB_SHNDX:
1167 if (!IO.outputting())
1168 Section.reset(new ELFYAML::SymtabShndxSection());
1169 sectionMapping(IO, *cast<ELFYAML::SymtabShndxSection>(Section.get()));
1170 break;
1171 case ELF::SHT_LLVM_ADDRSIG:
1172 if (!IO.outputting())
1173 Section.reset(new ELFYAML::AddrsigSection());
1174 sectionMapping(IO, *cast<ELFYAML::AddrsigSection>(Section.get()));
1175 break;
1176 default:
1177 if (!IO.outputting()) {
1178 StringRef Name;
1179 IO.mapOptional("Name", Name, StringRef());
1180 Name = ELFYAML::dropUniqueSuffix(Name);
1181
1182 if (ELFYAML::StackSizesSection::nameMatches(Name))
1183 Section = std::make_unique<ELFYAML::StackSizesSection>();
1184 else
1185 Section = std::make_unique<ELFYAML::RawContentSection>();
1186 }
1187
1188 if (auto S = dyn_cast<ELFYAML::RawContentSection>(Section.get()))
1189 sectionMapping(IO, *S);
1190 else
1191 sectionMapping(IO, *cast<ELFYAML::StackSizesSection>(Section.get()));
1192 }
1193}
1194
1195StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate(
1196 IO &io, std::unique_ptr<ELFYAML::Section> &Section) {
1197 if (const auto *RawSection =
1198 dyn_cast<ELFYAML::RawContentSection>(Section.get())) {
1199 if (RawSection->Size && RawSection->Content &&
1200 (uint64_t)(*RawSection->Size) < RawSection->Content->binary_size())
1201 return "Section size must be greater than or equal to the content size";
1202 return {};
1203 }
1204
1205 if (const auto *SS = dyn_cast<ELFYAML::StackSizesSection>(Section.get())) {
1206 if (!SS->Entries && !SS->Content && !SS->Size)
1207 return ".stack_sizes: one of Content, Entries and Size must be specified";
1208
1209 if (SS->Size && SS->Content &&
1210 (uint64_t)(*SS->Size) < SS->Content->binary_size())
1211 return ".stack_sizes: Size must be greater than or equal to the content "
1212 "size";
1213
1214 // We accept Content, Size or both together when there are no Entries.
1215 if (!SS->Entries)
1216 return {};
1217
1218 if (SS->Size)
1219 return ".stack_sizes: Size and Entries cannot be used together";
1220 if (SS->Content)
1221 return ".stack_sizes: Content and Entries cannot be used together";
1222 return {};
1223 }
1224
1225 if (const auto *HS = dyn_cast<ELFYAML::HashSection>(Section.get())) {
1226 if (!HS->Content && !HS->Bucket && !HS->Chain && !HS->Size)
1227 return "one of \"Content\", \"Size\", \"Bucket\" or \"Chain\" must be "
1228 "specified";
1229
1230 if (HS->Content || HS->Size) {
1231 if (HS->Size && HS->Content &&
1232 (uint64_t)*HS->Size < HS->Content->binary_size())
1233 return "\"Size\" must be greater than or equal to the content "
1234 "size";
1235
1236 if (HS->Bucket)
1237 return "\"Bucket\" cannot be used with \"Content\" or \"Size\"";
1238 if (HS->Chain)
1239 return "\"Chain\" cannot be used with \"Content\" or \"Size\"";
1240 return {};
1241 }
1242
1243 if ((HS->Bucket && !HS->Chain) || (!HS->Bucket && HS->Chain))
1244 return "\"Bucket\" and \"Chain\" must be used together";
1245 return {};
1246 }
1247
1248 if (const auto *Sec = dyn_cast<ELFYAML::AddrsigSection>(Section.get())) {
1249 if (!Sec->Symbols && !Sec->Content && !Sec->Size)
1250 return "one of \"Content\", \"Size\" or \"Symbols\" must be specified";
1251
1252 if (Sec->Content || Sec->Size) {
1253 if (Sec->Size && Sec->Content &&
1254 (uint64_t)*Sec->Size < Sec->Content->binary_size())
1255 return "\"Size\" must be greater than or equal to the content "
1256 "size";
1257
1258 if (Sec->Symbols)
1259 return "\"Symbols\" cannot be used with \"Content\" or \"Size\"";
1260 return {};
1261 }
1262
1263 if (!Sec->Symbols)
1264 return {};
1265
1266 for (const ELFYAML::AddrsigSymbol &AS : *Sec->Symbols)
1267 if (AS.Index && AS.Name)
1268 return "\"Index\" and \"Name\" cannot be used together when defining a "
1269 "symbol";
1270 return {};
1271 }
1272
1273 return {};
1274}
1275
1276namespace {
1277
1278struct NormalizedMips64RelType {
1279 NormalizedMips64RelType(IO &)
1280 : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1281 Type2(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1282 Type3(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1283 SpecSym(ELFYAML::ELF_REL(ELF::RSS_UNDEF)) {}
1284 NormalizedMips64RelType(IO &, ELFYAML::ELF_REL Original)
1285 : Type(Original & 0xFF), Type2(Original >> 8 & 0xFF),
1286 Type3(Original >> 16 & 0xFF), SpecSym(Original >> 24 & 0xFF) {}
1287
1288 ELFYAML::ELF_REL denormalize(IO &) {
1289 ELFYAML::ELF_REL Res = Type | Type2 << 8 | Type3 << 16 | SpecSym << 24;
1290 return Res;
1291 }
1292
1293 ELFYAML::ELF_REL Type;
1294 ELFYAML::ELF_REL Type2;
1295 ELFYAML::ELF_REL Type3;
1296 ELFYAML::ELF_RSS SpecSym;
1297};
1298
1299} // end anonymous namespace
1300
1301void MappingTraits<ELFYAML::StackSizeEntry>::mapping(
1302 IO &IO, ELFYAML::StackSizeEntry &E) {
1303 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 1303, __PRETTY_FUNCTION__))
;
1304 IO.mapOptional("Address", E.Address, Hex64(0));
1305 IO.mapRequired("Size", E.Size);
1306}
1307
1308void MappingTraits<ELFYAML::DynamicEntry>::mapping(IO &IO,
1309 ELFYAML::DynamicEntry &Rel) {
1310 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 1310, __PRETTY_FUNCTION__))
;
1311
1312 IO.mapRequired("Tag", Rel.Tag);
1313 IO.mapRequired("Value", Rel.Val);
1314}
1315
1316void MappingTraits<ELFYAML::VerdefEntry>::mapping(IO &IO,
1317 ELFYAML::VerdefEntry &E) {
1318 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 1318, __PRETTY_FUNCTION__))
;
1319
1320 IO.mapRequired("Version", E.Version);
1321 IO.mapRequired("Flags", E.Flags);
1322 IO.mapRequired("VersionNdx", E.VersionNdx);
1323 IO.mapRequired("Hash", E.Hash);
1324 IO.mapRequired("Names", E.VerNames);
1325}
1326
1327void MappingTraits<ELFYAML::VerneedEntry>::mapping(IO &IO,
1328 ELFYAML::VerneedEntry &E) {
1329 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 1329, __PRETTY_FUNCTION__))
;
1330
1331 IO.mapRequired("Version", E.Version);
1332 IO.mapRequired("File", E.File);
1333 IO.mapRequired("Entries", E.AuxV);
1334}
1335
1336void MappingTraits<ELFYAML::VernauxEntry>::mapping(IO &IO,
1337 ELFYAML::VernauxEntry &E) {
1338 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 1338, __PRETTY_FUNCTION__))
;
1339
1340 IO.mapRequired("Name", E.Name);
1341 IO.mapRequired("Hash", E.Hash);
1342 IO.mapRequired("Flags", E.Flags);
1343 IO.mapRequired("Other", E.Other);
1344}
1345
1346void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
1347 ELFYAML::Relocation &Rel) {
1348 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
1349 assert(Object && "The IO context is not initialized")((Object && "The IO context is not initialized") ? static_cast
<void> (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 1349, __PRETTY_FUNCTION__))
;
1350
1351 IO.mapRequired("Offset", Rel.Offset);
1352 IO.mapOptional("Symbol", Rel.Symbol);
1353
1354 if (Object->Header.Machine == ELFYAML::ELF_EM(ELF::EM_MIPS) &&
1355 Object->Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64)) {
1356 MappingNormalization<NormalizedMips64RelType, ELFYAML::ELF_REL> Key(
1357 IO, Rel.Type);
1358 IO.mapRequired("Type", Key->Type);
1359 IO.mapOptional("Type2", Key->Type2, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
1360 IO.mapOptional("Type3", Key->Type3, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
1361 IO.mapOptional("SpecSym", Key->SpecSym, ELFYAML::ELF_RSS(ELF::RSS_UNDEF));
1362 } else
1363 IO.mapRequired("Type", Rel.Type);
1364
1365 IO.mapOptional("Addend", Rel.Addend, (int64_t)0);
1366}
1367
1368void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
1369 assert(!IO.getContext() && "The IO context is initialized already")((!IO.getContext() && "The IO context is initialized already"
) ? static_cast<void> (0) : __assert_fail ("!IO.getContext() && \"The IO context is initialized already\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 1369, __PRETTY_FUNCTION__))
;
1370 IO.setContext(&Object);
1371 IO.mapTag("!ELF", true);
1372 IO.mapRequired("FileHeader", Object.Header);
1373 IO.mapOptional("ProgramHeaders", Object.ProgramHeaders);
1374 IO.mapOptional("Sections", Object.Sections);
1375 IO.mapOptional("Symbols", Object.Symbols);
1376 IO.mapOptional("DynamicSymbols", Object.DynamicSymbols);
1377 IO.setContext(nullptr);
1378}
1379
1380void MappingTraits<ELFYAML::AddrsigSymbol>::mapping(IO &IO, ELFYAML::AddrsigSymbol &Sym) {
1381 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/ObjectYAML/ELFYAML.cpp"
, 1381, __PRETTY_FUNCTION__))
;
1382 IO.mapOptional("Name", Sym.Name);
1383 IO.mapOptional("Index", Sym.Index);
1384}
1385
1386LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)struct MIPS_AFL_REG { MIPS_AFL_REG() = default; MIPS_AFL_REG(
const uint8_t v) : value(v) {} MIPS_AFL_REG(const MIPS_AFL_REG
&v) = default; MIPS_AFL_REG &operator=(const MIPS_AFL_REG
&rhs) = default; MIPS_AFL_REG &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const MIPS_AFL_REG
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_REG &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
1387LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)struct MIPS_ABI_FP { MIPS_ABI_FP() = default; MIPS_ABI_FP(const
uint8_t v) : value(v) {} MIPS_ABI_FP(const MIPS_ABI_FP &
v) = default; MIPS_ABI_FP &operator=(const MIPS_ABI_FP &
rhs) = default; MIPS_ABI_FP &operator=(const uint8_t &
rhs) { value = rhs; return *this; } operator const uint8_t &
() const { return value; } bool operator==(const MIPS_ABI_FP
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_ABI_FP &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
1388LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)struct MIPS_AFL_EXT { MIPS_AFL_EXT() = default; MIPS_AFL_EXT(
const uint32_t v) : value(v) {} MIPS_AFL_EXT(const MIPS_AFL_EXT
&v) = default; MIPS_AFL_EXT &operator=(const MIPS_AFL_EXT
&rhs) = default; MIPS_AFL_EXT &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_EXT
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_EXT &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
1389LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)struct MIPS_AFL_ASE { MIPS_AFL_ASE() = default; MIPS_AFL_ASE(
const uint32_t v) : value(v) {} MIPS_AFL_ASE(const MIPS_AFL_ASE
&v) = default; MIPS_AFL_ASE &operator=(const MIPS_AFL_ASE
&rhs) = default; MIPS_AFL_ASE &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_ASE
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_ASE &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
1390LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)struct MIPS_AFL_FLAGS1 { MIPS_AFL_FLAGS1() = default; MIPS_AFL_FLAGS1
(const uint32_t v) : value(v) {} MIPS_AFL_FLAGS1(const MIPS_AFL_FLAGS1
&v) = default; MIPS_AFL_FLAGS1 &operator=(const MIPS_AFL_FLAGS1
&rhs) = default; MIPS_AFL_FLAGS1 &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_FLAGS1
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_FLAGS1 &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
1391
1392} // end namespace yaml
1393
1394} // end namespace llvm

/build/llvm-toolchain-snapshot-10~svn374877/include/llvm/ObjectYAML/ELFYAML.h

1//===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file declares classes for handling the YAML representation
11/// of ELF.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_OBJECTYAML_ELFYAML_H
16#define LLVM_OBJECTYAML_ELFYAML_H
17
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ObjectYAML/YAML.h"
20#include "llvm/Support/YAMLTraits.h"
21#include <cstdint>
22#include <memory>
23#include <vector>
24
25namespace llvm {
26namespace ELFYAML {
27
28StringRef dropUniqueSuffix(StringRef S);
29
30// These types are invariant across 32/64-bit ELF, so for simplicity just
31// directly give them their exact sizes. We don't need to worry about
32// endianness because these are just the types in the YAMLIO structures,
33// and are appropriately converted to the necessary endianness when
34// reading/generating binary object files.
35// The naming of these types is intended to be ELF_PREFIX, where PREFIX is
36// the common prefix of the respective constants. E.g. ELF_EM corresponds
37// to the `e_machine` constants, like `EM_X86_64`.
38// In the future, these would probably be better suited by C++11 enum
39// class's with appropriate fixed underlying type.
40LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)struct ELF_ET { ELF_ET() = default; ELF_ET(const uint16_t v) :
value(v) {} ELF_ET(const ELF_ET &v) = default; ELF_ET &
operator=(const ELF_ET &rhs) = default; ELF_ET &operator
=(const uint16_t &rhs) { value = rhs; return *this; } operator
const uint16_t & () const { return value; } bool operator
==(const ELF_ET &rhs) const { return value == rhs.value; }
bool operator==(const uint16_t &rhs) const { return value
== rhs; } bool operator<(const ELF_ET &rhs) const { return
value < rhs.value; } uint16_t value; using BaseType = uint16_t
; };
41LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)struct ELF_PT { ELF_PT() = default; ELF_PT(const uint32_t v) :
value(v) {} ELF_PT(const ELF_PT &v) = default; ELF_PT &
operator=(const ELF_PT &rhs) = default; ELF_PT &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_PT &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_PT &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
42LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)struct ELF_EM { ELF_EM() = default; ELF_EM(const uint32_t v) :
value(v) {} ELF_EM(const ELF_EM &v) = default; ELF_EM &
operator=(const ELF_EM &rhs) = default; ELF_EM &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_EM &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_EM &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
43LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)struct ELF_ELFCLASS { ELF_ELFCLASS() = default; ELF_ELFCLASS(
const uint8_t v) : value(v) {} ELF_ELFCLASS(const ELF_ELFCLASS
&v) = default; ELF_ELFCLASS &operator=(const ELF_ELFCLASS
&rhs) = default; ELF_ELFCLASS &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const ELF_ELFCLASS
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFCLASS &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
44LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)struct ELF_ELFDATA { ELF_ELFDATA() = default; ELF_ELFDATA(const
uint8_t v) : value(v) {} ELF_ELFDATA(const ELF_ELFDATA &
v) = default; ELF_ELFDATA &operator=(const ELF_ELFDATA &
rhs) = default; ELF_ELFDATA &operator=(const uint8_t &
rhs) { value = rhs; return *this; } operator const uint8_t &
() const { return value; } bool operator==(const ELF_ELFDATA
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFDATA &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
45LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)struct ELF_ELFOSABI { ELF_ELFOSABI() = default; ELF_ELFOSABI(
const uint8_t v) : value(v) {} ELF_ELFOSABI(const ELF_ELFOSABI
&v) = default; ELF_ELFOSABI &operator=(const ELF_ELFOSABI
&rhs) = default; ELF_ELFOSABI &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const ELF_ELFOSABI
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFOSABI &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
46// Just use 64, since it can hold 32-bit values too.
47LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)struct ELF_EF { ELF_EF() = default; ELF_EF(const uint64_t v) :
value(v) {} ELF_EF(const ELF_EF &v) = default; ELF_EF &
operator=(const ELF_EF &rhs) = default; ELF_EF &operator
=(const uint64_t &rhs) { value = rhs; return *this; } operator
const uint64_t & () const { return value; } bool operator
==(const ELF_EF &rhs) const { return value == rhs.value; }
bool operator==(const uint64_t &rhs) const { return value
== rhs; } bool operator<(const ELF_EF &rhs) const { return
value < rhs.value; } uint64_t value; using BaseType = uint64_t
; };
48// Just use 64, since it can hold 32-bit values too.
49LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)struct ELF_DYNTAG { ELF_DYNTAG() = default; ELF_DYNTAG(const uint64_t
v) : value(v) {} ELF_DYNTAG(const ELF_DYNTAG &v) = default
; ELF_DYNTAG &operator=(const ELF_DYNTAG &rhs) = default
; ELF_DYNTAG &operator=(const uint64_t &rhs) { value =
rhs; return *this; } operator const uint64_t & () const {
return value; } bool operator==(const ELF_DYNTAG &rhs) const
{ return value == rhs.value; } bool operator==(const uint64_t
&rhs) const { return value == rhs; } bool operator<(const
ELF_DYNTAG &rhs) const { return value < rhs.value; } uint64_t
value; using BaseType = uint64_t; };
50LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)struct ELF_PF { ELF_PF() = default; ELF_PF(const uint32_t v) :
value(v) {} ELF_PF(const ELF_PF &v) = default; ELF_PF &
operator=(const ELF_PF &rhs) = default; ELF_PF &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_PF &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_PF &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
51LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)struct ELF_SHT { ELF_SHT() = default; ELF_SHT(const uint32_t v
) : value(v) {} ELF_SHT(const ELF_SHT &v) = default; ELF_SHT
&operator=(const ELF_SHT &rhs) = default; ELF_SHT &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const ELF_SHT &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHT &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
2
Returning without writing to 'this->value'
52LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)struct ELF_REL { ELF_REL() = default; ELF_REL(const uint32_t v
) : value(v) {} ELF_REL(const ELF_REL &v) = default; ELF_REL
&operator=(const ELF_REL &rhs) = default; ELF_REL &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const ELF_REL &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const ELF_REL &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
53LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)struct ELF_RSS { ELF_RSS() = default; ELF_RSS(const uint8_t v
) : value(v) {} ELF_RSS(const ELF_RSS &v) = default; ELF_RSS
&operator=(const ELF_RSS &rhs) = default; ELF_RSS &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_RSS &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_RSS &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
54// Just use 64, since it can hold 32-bit values too.
55LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)struct ELF_SHF { ELF_SHF() = default; ELF_SHF(const uint64_t v
) : value(v) {} ELF_SHF(const ELF_SHF &v) = default; ELF_SHF
&operator=(const ELF_SHF &rhs) = default; ELF_SHF &
operator=(const uint64_t &rhs) { value = rhs; return *this
; } operator const uint64_t & () const { return value; } bool
operator==(const ELF_SHF &rhs) const { return value == rhs
.value; } bool operator==(const uint64_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHF &rhs) const
{ return value < rhs.value; } uint64_t value; using BaseType
= uint64_t; };
56LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)struct ELF_SHN { ELF_SHN() = default; ELF_SHN(const uint16_t v
) : value(v) {} ELF_SHN(const ELF_SHN &v) = default; ELF_SHN
&operator=(const ELF_SHN &rhs) = default; ELF_SHN &
operator=(const uint16_t &rhs) { value = rhs; return *this
; } operator const uint16_t & () const { return value; } bool
operator==(const ELF_SHN &rhs) const { return value == rhs
.value; } bool operator==(const uint16_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHN &rhs) const
{ return value < rhs.value; } uint16_t value; using BaseType
= uint16_t; };
57LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)struct ELF_STB { ELF_STB() = default; ELF_STB(const uint8_t v
) : value(v) {} ELF_STB(const ELF_STB &v) = default; ELF_STB
&operator=(const ELF_STB &rhs) = default; ELF_STB &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_STB &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_STB &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
58LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)struct ELF_STT { ELF_STT() = default; ELF_STT(const uint8_t v
) : value(v) {} ELF_STT(const ELF_STT &v) = default; ELF_STT
&operator=(const ELF_STT &rhs) = default; ELF_STT &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_STT &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_STT &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
59
60LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)struct MIPS_AFL_REG { MIPS_AFL_REG() = default; MIPS_AFL_REG(
const uint8_t v) : value(v) {} MIPS_AFL_REG(const MIPS_AFL_REG
&v) = default; MIPS_AFL_REG &operator=(const MIPS_AFL_REG
&rhs) = default; MIPS_AFL_REG &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const MIPS_AFL_REG
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_REG &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
61LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)struct MIPS_ABI_FP { MIPS_ABI_FP() = default; MIPS_ABI_FP(const
uint8_t v) : value(v) {} MIPS_ABI_FP(const MIPS_ABI_FP &
v) = default; MIPS_ABI_FP &operator=(const MIPS_ABI_FP &
rhs) = default; MIPS_ABI_FP &operator=(const uint8_t &
rhs) { value = rhs; return *this; } operator const uint8_t &
() const { return value; } bool operator==(const MIPS_ABI_FP
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_ABI_FP &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
62LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)struct MIPS_AFL_EXT { MIPS_AFL_EXT() = default; MIPS_AFL_EXT(
const uint32_t v) : value(v) {} MIPS_AFL_EXT(const MIPS_AFL_EXT
&v) = default; MIPS_AFL_EXT &operator=(const MIPS_AFL_EXT
&rhs) = default; MIPS_AFL_EXT &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_EXT
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_EXT &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
63LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)struct MIPS_AFL_ASE { MIPS_AFL_ASE() = default; MIPS_AFL_ASE(
const uint32_t v) : value(v) {} MIPS_AFL_ASE(const MIPS_AFL_ASE
&v) = default; MIPS_AFL_ASE &operator=(const MIPS_AFL_ASE
&rhs) = default; MIPS_AFL_ASE &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_ASE
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_ASE &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
64LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)struct MIPS_AFL_FLAGS1 { MIPS_AFL_FLAGS1() = default; MIPS_AFL_FLAGS1
(const uint32_t v) : value(v) {} MIPS_AFL_FLAGS1(const MIPS_AFL_FLAGS1
&v) = default; MIPS_AFL_FLAGS1 &operator=(const MIPS_AFL_FLAGS1
&rhs) = default; MIPS_AFL_FLAGS1 &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_FLAGS1
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_FLAGS1 &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
65LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)struct MIPS_ISA { MIPS_ISA() = default; MIPS_ISA(const uint32_t
v) : value(v) {} MIPS_ISA(const MIPS_ISA &v) = default; MIPS_ISA
&operator=(const MIPS_ISA &rhs) = default; MIPS_ISA &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const MIPS_ISA &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const MIPS_ISA &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
66
67// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
68// since 64-bit can hold 32-bit values too.
69struct FileHeader {
70 ELF_ELFCLASS Class;
71 ELF_ELFDATA Data;
72 ELF_ELFOSABI OSABI;
73 llvm::yaml::Hex8 ABIVersion;
74 ELF_ET Type;
75 ELF_EM Machine;
76 ELF_EF Flags;
77 llvm::yaml::Hex64 Entry;
78
79 Optional<llvm::yaml::Hex16> SHEntSize;
80 Optional<llvm::yaml::Hex64> SHOff;
81 Optional<llvm::yaml::Hex16> SHNum;
82 Optional<llvm::yaml::Hex16> SHStrNdx;
83};
84
85struct SectionName {
86 StringRef Section;
87};
88
89struct ProgramHeader {
90 ELF_PT Type;
91 ELF_PF Flags;
92 llvm::yaml::Hex64 VAddr;
93 llvm::yaml::Hex64 PAddr;
94 Optional<llvm::yaml::Hex64> Align;
95 Optional<llvm::yaml::Hex64> FileSize;
96 Optional<llvm::yaml::Hex64> MemSize;
97 Optional<llvm::yaml::Hex64> Offset;
98 std::vector<SectionName> Sections;
99};
100
101struct Symbol {
102 StringRef Name;
103 Optional<uint32_t> NameIndex;
104 ELF_STT Type;
105 StringRef Section;
106 Optional<ELF_SHN> Index;
107 ELF_STB Binding;
108 llvm::yaml::Hex64 Value;
109 llvm::yaml::Hex64 Size;
110 Optional<uint8_t> Other;
111};
112
113struct SectionOrType {
114 StringRef sectionNameOrType;
115};
116
117struct DynamicEntry {
118 ELF_DYNTAG Tag;
119 llvm::yaml::Hex64 Val;
120};
121
122struct StackSizeEntry {
123 llvm::yaml::Hex64 Address;
124 llvm::yaml::Hex64 Size;
125};
126
127struct Section {
128 enum class SectionKind {
129 Dynamic,
130 Group,
131 RawContent,
132 Relocation,
133 NoBits,
134 Hash,
135 Verdef,
136 Verneed,
137 StackSizes,
138 SymtabShndxSection,
139 Symver,
140 MipsABIFlags,
141 Addrsig
142 };
143 SectionKind Kind;
144 StringRef Name;
145 ELF_SHT Type;
146 Optional<ELF_SHF> Flags;
147 llvm::yaml::Hex64 Address;
148 StringRef Link;
149 llvm::yaml::Hex64 AddressAlign;
150 Optional<llvm::yaml::Hex64> EntSize;
151
152 // Usually sections are not created implicitly, but loaded from YAML.
153 // When they are, this flag is used to signal about that.
154 bool IsImplicit;
155
156 Section(SectionKind Kind, bool IsImplicit = false)
157 : Kind(Kind), IsImplicit(IsImplicit) {}
158 virtual ~Section();
159
160 // The following members are used to override section fields which is
161 // useful for creating invalid objects.
162
163 // This can be used to override the offset stored in the sh_name field.
164 // It does not affect the name stored in the string table.
165 Optional<llvm::yaml::Hex64> ShName;
166
167 // This can be used to override the sh_offset field. It does not place the
168 // section data at the offset specified.
169 Optional<llvm::yaml::Hex64> ShOffset;
170
171 // This can be used to override the sh_size field. It does not affect the
172 // content written.
173 Optional<llvm::yaml::Hex64> ShSize;
174};
175
176struct StackSizesSection : Section {
177 Optional<yaml::BinaryRef> Content;
178 Optional<llvm::yaml::Hex64> Size;
179 Optional<std::vector<StackSizeEntry>> Entries;
180
181 StackSizesSection() : Section(SectionKind::StackSizes) {}
182
183 static bool classof(const Section *S) {
184 return S->Kind == SectionKind::StackSizes;
185 }
186
187 static bool nameMatches(StringRef Name) {
188 return Name == ".stack_sizes";
189 }
190};
191
192struct DynamicSection : Section {
193 std::vector<DynamicEntry> Entries;
194 Optional<yaml::BinaryRef> Content;
195
196 DynamicSection() : Section(SectionKind::Dynamic) {}
197
198 static bool classof(const Section *S) {
199 return S->Kind == SectionKind::Dynamic;
200 }
201};
202
203struct RawContentSection : Section {
204 Optional<yaml::BinaryRef> Content;
205 Optional<llvm::yaml::Hex64> Size;
206 Optional<llvm::yaml::Hex64> Info;
207
208 RawContentSection() : Section(SectionKind::RawContent) {}
209
210 static bool classof(const Section *S) {
211 return S->Kind == SectionKind::RawContent;
212 }
213};
214
215struct NoBitsSection : Section {
216 llvm::yaml::Hex64 Size;
217
218 NoBitsSection() : Section(SectionKind::NoBits) {}
219
220 static bool classof(const Section *S) {
221 return S->Kind == SectionKind::NoBits;
222 }
223};
224
225struct HashSection : Section {
226 Optional<yaml::BinaryRef> Content;
227 Optional<llvm::yaml::Hex64> Size;
228 Optional<std::vector<uint32_t>> Bucket;
229 Optional<std::vector<uint32_t>> Chain;
230
231 HashSection() : Section(SectionKind::Hash) {}
232
233 static bool classof(const Section *S) { return S->Kind == SectionKind::Hash; }
234};
235
236struct VernauxEntry {
237 uint32_t Hash;
238 uint16_t Flags;
239 uint16_t Other;
240 StringRef Name;
241};
242
243struct VerneedEntry {
244 uint16_t Version;
245 StringRef File;
246 std::vector<VernauxEntry> AuxV;
247};
248
249struct VerneedSection : Section {
250 std::vector<VerneedEntry> VerneedV;
251 llvm::yaml::Hex64 Info;
252
253 VerneedSection() : Section(SectionKind::Verneed) {}
254
255 static bool classof(const Section *S) {
256 return S->Kind == SectionKind::Verneed;
257 }
258};
259
260struct AddrsigSymbol {
261 AddrsigSymbol(StringRef N) : Name(N), Index(None) {}
262 AddrsigSymbol(llvm::yaml::Hex32 Ndx) : Name(None), Index(Ndx) {}
263 AddrsigSymbol() : Name(None), Index(None) {}
264
265 Optional<StringRef> Name;
266 Optional<llvm::yaml::Hex32> Index;
267};
268
269struct AddrsigSection : Section {
270 Optional<yaml::BinaryRef> Content;
271 Optional<llvm::yaml::Hex64> Size;
272 Optional<std::vector<AddrsigSymbol>> Symbols;
273
274 AddrsigSection() : Section(SectionKind::Addrsig) {}
275 static bool classof(const Section *S) {
276 return S->Kind == SectionKind::Addrsig;
277 }
278};
279
280struct SymverSection : Section {
281 std::vector<uint16_t> Entries;
282
283 SymverSection() : Section(SectionKind::Symver) {}
284
285 static bool classof(const Section *S) {
286 return S->Kind == SectionKind::Symver;
287 }
288};
289
290struct VerdefEntry {
291 uint16_t Version;
292 uint16_t Flags;
293 uint16_t VersionNdx;
294 uint32_t Hash;
295 std::vector<StringRef> VerNames;
296};
297
298struct VerdefSection : Section {
299 std::vector<VerdefEntry> Entries;
300 llvm::yaml::Hex64 Info;
301
302 VerdefSection() : Section(SectionKind::Verdef) {}
303
304 static bool classof(const Section *S) {
305 return S->Kind == SectionKind::Verdef;
306 }
307};
308
309struct Group : Section {
310 // Members of a group contain a flag and a list of section indices
311 // that are part of the group.
312 std::vector<SectionOrType> Members;
313 StringRef Signature; /* Info */
314
315 Group() : Section(SectionKind::Group) {}
316
317 static bool classof(const Section *S) {
318 return S->Kind == SectionKind::Group;
319 }
320};
321
322struct Relocation {
323 llvm::yaml::Hex64 Offset;
324 int64_t Addend;
325 ELF_REL Type;
326 Optional<StringRef> Symbol;
327};
328
329struct RelocationSection : Section {
330 std::vector<Relocation> Relocations;
331 StringRef RelocatableSec; /* Info */
332
333 RelocationSection() : Section(SectionKind::Relocation) {}
334
335 static bool classof(const Section *S) {
336 return S->Kind == SectionKind::Relocation;
337 }
338};
339
340struct SymtabShndxSection : Section {
341 std::vector<uint32_t> Entries;
342
343 SymtabShndxSection() : Section(SectionKind::SymtabShndxSection) {}
344
345 static bool classof(const Section *S) {
346 return S->Kind == SectionKind::SymtabShndxSection;
347 }
348};
349
350// Represents .MIPS.abiflags section
351struct MipsABIFlags : Section {
352 llvm::yaml::Hex16 Version;
353 MIPS_ISA ISALevel;
354 llvm::yaml::Hex8 ISARevision;
355 MIPS_AFL_REG GPRSize;
356 MIPS_AFL_REG CPR1Size;
357 MIPS_AFL_REG CPR2Size;
358 MIPS_ABI_FP FpABI;
359 MIPS_AFL_EXT ISAExtension;
360 MIPS_AFL_ASE ASEs;
361 MIPS_AFL_FLAGS1 Flags1;
362 llvm::yaml::Hex32 Flags2;
363
364 MipsABIFlags() : Section(SectionKind::MipsABIFlags) {}
365
366 static bool classof(const Section *S) {
367 return S->Kind == SectionKind::MipsABIFlags;
368 }
369};
370
371struct Object {
372 FileHeader Header;
373 std::vector<ProgramHeader> ProgramHeaders;
374 std::vector<std::unique_ptr<Section>> Sections;
375 // Although in reality the symbols reside in a section, it is a lot
376 // cleaner and nicer if we read them from the YAML as a separate
377 // top-level key, which automatically ensures that invariants like there
378 // being a single SHT_SYMTAB section are upheld.
379 std::vector<Symbol> Symbols;
380 std::vector<Symbol> DynamicSymbols;
381};
382
383} // end namespace ELFYAML
384} // end namespace llvm
385
386LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::AddrsigSymbol)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::AddrsigSymbol>::value && !std::
is_same<llvm::ELFYAML::AddrsigSymbol, std::string>::value
&& !std::is_same<llvm::ELFYAML::AddrsigSymbol, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::AddrsigSymbol> { static const bool flow = false; }; } }
387LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::StackSizeEntry>::value && !std::
is_same<llvm::ELFYAML::StackSizeEntry, std::string>::value
&& !std::is_same<llvm::ELFYAML::StackSizeEntry, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::StackSizeEntry> { static const bool flow = false; }; } }
388LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::DynamicEntry>::value && !std::is_same
<llvm::ELFYAML::DynamicEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::DynamicEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::DynamicEntry> { static const bool flow = false; }; } }
389LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::ProgramHeader>::value && !std::
is_same<llvm::ELFYAML::ProgramHeader, std::string>::value
&& !std::is_same<llvm::ELFYAML::ProgramHeader, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::ProgramHeader> { static const bool flow = false; }; } }
390LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<std::unique_ptr<llvm::ELFYAML::Section> >::value
&& !std::is_same<std::unique_ptr<llvm::ELFYAML
::Section>, std::string>::value && !std::is_same
<std::unique_ptr<llvm::ELFYAML::Section>, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<std::unique_ptr
<llvm::ELFYAML::Section> > { static const bool flow =
false; }; } }
391LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::Symbol>::value && !std::is_same
<llvm::ELFYAML::Symbol, std::string>::value && !
std::is_same<llvm::ELFYAML::Symbol, llvm::StringRef>::value
, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::Symbol> { static const bool flow = false; }; } }
392LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::VerdefEntry>::value && !std::is_same
<llvm::ELFYAML::VerdefEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::VerdefEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VerdefEntry> { static const bool flow = false; }; } }
393LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::VernauxEntry>::value && !std::is_same
<llvm::ELFYAML::VernauxEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::VernauxEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VernauxEntry> { static const bool flow = false; }; } }
394LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::VerneedEntry>::value && !std::is_same
<llvm::ELFYAML::VerneedEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::VerneedEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VerneedEntry> { static const bool flow = false; }; } }
395LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::Relocation>::value && !std::is_same
<llvm::ELFYAML::Relocation, std::string>::value &&
!std::is_same<llvm::ELFYAML::Relocation, llvm::StringRef>
::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::Relocation> { static const bool flow = false; }; } }
396LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::SectionOrType>::value && !std::
is_same<llvm::ELFYAML::SectionOrType, std::string>::value
&& !std::is_same<llvm::ELFYAML::SectionOrType, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::SectionOrType> { static const bool flow = false; }; } }
397LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::SectionName>::value && !std::is_same
<llvm::ELFYAML::SectionName, std::string>::value &&
!std::is_same<llvm::ELFYAML::SectionName, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::SectionName> { static const bool flow = false; }; } }
398
399namespace llvm {
400namespace yaml {
401
402template <>
403struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
404 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
405};
406
407template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
408 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
409};
410
411template <>
412struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
413 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
414};
415
416template <>
417struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
418 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
419};
420
421template <>
422struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
423 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
424};
425
426template <>
427struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
428 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
429};
430
431template <>
432struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
433 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
434};
435
436template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
437 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
438};
439
440template <>
441struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
442 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
443};
444
445template <>
446struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
447 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
448};
449
450template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
451 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
452};
453
454template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
455 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
456};
457
458template <>
459struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
460 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
461};
462
463template <>
464struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
465 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
466};
467
468template <>
469struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
470 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
471};
472
473template <>
474struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
475 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
476};
477
478template <>
479struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
480 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
481};
482
483template <>
484struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
485 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
486};
487
488template <>
489struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
490 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
491};
492
493template <>
494struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
495 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
496};
497
498template <>
499struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
500 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
501};
502
503template <>
504struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
505 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
506};
507
508template <>
509struct MappingTraits<ELFYAML::FileHeader> {
510 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
511};
512
513template <> struct MappingTraits<ELFYAML::ProgramHeader> {
514 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
515};
516
517template <>
518struct MappingTraits<ELFYAML::Symbol> {
519 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
520 static StringRef validate(IO &IO, ELFYAML::Symbol &Symbol);
521};
522
523template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
524 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
525};
526
527template <> struct MappingTraits<ELFYAML::DynamicEntry> {
528 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
529};
530
531template <> struct MappingTraits<ELFYAML::VerdefEntry> {
532 static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
533};
534
535template <> struct MappingTraits<ELFYAML::VerneedEntry> {
536 static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
537};
538
539template <> struct MappingTraits<ELFYAML::VernauxEntry> {
540 static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
541};
542
543template <> struct MappingTraits<ELFYAML::AddrsigSymbol> {
544 static void mapping(IO &IO, ELFYAML::AddrsigSymbol &Sym);
545};
546
547template <> struct MappingTraits<ELFYAML::Relocation> {
548 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
549};
550
551template <>
552struct MappingTraits<std::unique_ptr<ELFYAML::Section>> {
553 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Section> &Section);
554 static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Section> &Section);
555};
556
557template <>
558struct MappingTraits<ELFYAML::Object> {
559 static void mapping(IO &IO, ELFYAML::Object &Object);
560};
561
562template <> struct MappingTraits<ELFYAML::SectionOrType> {
563 static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
564};
565
566template <> struct MappingTraits<ELFYAML::SectionName> {
567 static void mapping(IO &IO, ELFYAML::SectionName &sectionName);
568};
569
570} // end namespace yaml
571} // end namespace llvm
572
573#endif // LLVM_OBJECTYAML_ELFYAML_H

/build/llvm-toolchain-snapshot-10~svn374877/include/llvm/Support/YAMLTraits.h

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