Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ELFYAML.cpp -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 -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-17/lib/clang/17 -D _DEBUG -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D _LIBCPP_ENABLE_ASSERTIONS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I lib/ObjectYAML -I /build/source/llvm/lib/ObjectYAML -I include -I /build/source/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/source/= -source-date-epoch 1683717183 -O2 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-05-10-133810-16478-1 -x c++ /build/source/llvm/lib/ObjectYAML/ELFYAML.cpp

/build/source/llvm/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/APInt.h"
15#include "llvm/ADT/MapVector.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/BinaryFormat/ELF.h"
18#include "llvm/Support/ARMEHABI.h"
19#include "llvm/Support/Casting.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/MipsABIFlags.h"
22#include "llvm/Support/YAMLTraits.h"
23#include "llvm/Support/WithColor.h"
24#include <cassert>
25#include <cstdint>
26#include <optional>
27
28namespace llvm {
29
30ELFYAML::Chunk::~Chunk() = default;
31
32namespace ELFYAML {
33ELF_ELFOSABI Object::getOSAbi() const { return Header.OSABI; }
34
35unsigned Object::getMachine() const {
36 if (Header.Machine)
37 return *Header.Machine;
38 return llvm::ELF::EM_NONE;
39}
40
41constexpr StringRef SectionHeaderTable::TypeStr;
42} // namespace ELFYAML
43
44namespace yaml {
45
46void ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration(
47 IO &IO, ELFYAML::ELF_ET &Value) {
48#define ECase(X) IO.enumCase(Value, #X, ELF::X)
49 ECase(ET_NONE);
50 ECase(ET_REL);
51 ECase(ET_EXEC);
52 ECase(ET_DYN);
53 ECase(ET_CORE);
54#undef ECase
55 IO.enumFallback<Hex16>(Value);
56}
57
58void ScalarEnumerationTraits<ELFYAML::ELF_PT>::enumeration(
59 IO &IO, ELFYAML::ELF_PT &Value) {
60#define ECase(X) IO.enumCase(Value, #X, ELF::X)
61 ECase(PT_NULL);
62 ECase(PT_LOAD);
63 ECase(PT_DYNAMIC);
64 ECase(PT_INTERP);
65 ECase(PT_NOTE);
66 ECase(PT_SHLIB);
67 ECase(PT_PHDR);
68 ECase(PT_TLS);
69 ECase(PT_GNU_EH_FRAME);
70 ECase(PT_GNU_STACK);
71 ECase(PT_GNU_RELRO);
72 ECase(PT_GNU_PROPERTY);
73#undef ECase
74 IO.enumFallback<Hex32>(Value);
75}
76
77void ScalarEnumerationTraits<ELFYAML::ELF_NT>::enumeration(
78 IO &IO, ELFYAML::ELF_NT &Value) {
79#define ECase(X) IO.enumCase(Value, #X, ELF::X)
80 // Generic note types.
81 ECase(NT_VERSION);
82 ECase(NT_ARCH);
83 ECase(NT_GNU_BUILD_ATTRIBUTE_OPEN);
84 ECase(NT_GNU_BUILD_ATTRIBUTE_FUNC);
85 // Core note types.
86 ECase(NT_PRSTATUS);
87 ECase(NT_FPREGSET);
88 ECase(NT_PRPSINFO);
89 ECase(NT_TASKSTRUCT);
90 ECase(NT_AUXV);
91 ECase(NT_PSTATUS);
92 ECase(NT_FPREGS);
93 ECase(NT_PSINFO);
94 ECase(NT_LWPSTATUS);
95 ECase(NT_LWPSINFO);
96 ECase(NT_WIN32PSTATUS);
97 ECase(NT_PPC_VMX);
98 ECase(NT_PPC_VSX);
99 ECase(NT_PPC_TAR);
100 ECase(NT_PPC_PPR);
101 ECase(NT_PPC_DSCR);
102 ECase(NT_PPC_EBB);
103 ECase(NT_PPC_PMU);
104 ECase(NT_PPC_TM_CGPR);
105 ECase(NT_PPC_TM_CFPR);
106 ECase(NT_PPC_TM_CVMX);
107 ECase(NT_PPC_TM_CVSX);
108 ECase(NT_PPC_TM_SPR);
109 ECase(NT_PPC_TM_CTAR);
110 ECase(NT_PPC_TM_CPPR);
111 ECase(NT_PPC_TM_CDSCR);
112 ECase(NT_386_TLS);
113 ECase(NT_386_IOPERM);
114 ECase(NT_X86_XSTATE);
115 ECase(NT_S390_HIGH_GPRS);
116 ECase(NT_S390_TIMER);
117 ECase(NT_S390_TODCMP);
118 ECase(NT_S390_TODPREG);
119 ECase(NT_S390_CTRS);
120 ECase(NT_S390_PREFIX);
121 ECase(NT_S390_LAST_BREAK);
122 ECase(NT_S390_SYSTEM_CALL);
123 ECase(NT_S390_TDB);
124 ECase(NT_S390_VXRS_LOW);
125 ECase(NT_S390_VXRS_HIGH);
126 ECase(NT_S390_GS_CB);
127 ECase(NT_S390_GS_BC);
128 ECase(NT_ARM_VFP);
129 ECase(NT_ARM_TLS);
130 ECase(NT_ARM_HW_BREAK);
131 ECase(NT_ARM_HW_WATCH);
132 ECase(NT_ARM_SVE);
133 ECase(NT_ARM_PAC_MASK);
134 ECase(NT_ARM_SSVE);
135 ECase(NT_ARM_ZA);
136 ECase(NT_ARM_ZT);
137 ECase(NT_FILE);
138 ECase(NT_PRXFPREG);
139 ECase(NT_SIGINFO);
140 // LLVM-specific notes.
141 ECase(NT_LLVM_HWASAN_GLOBALS);
142 // GNU note types
143 ECase(NT_GNU_ABI_TAG);
144 ECase(NT_GNU_HWCAP);
145 ECase(NT_GNU_BUILD_ID);
146 ECase(NT_GNU_GOLD_VERSION);
147 ECase(NT_GNU_PROPERTY_TYPE_0);
148 // FreeBSD note types.
149 ECase(NT_FREEBSD_ABI_TAG);
150 ECase(NT_FREEBSD_NOINIT_TAG);
151 ECase(NT_FREEBSD_ARCH_TAG);
152 ECase(NT_FREEBSD_FEATURE_CTL);
153 // FreeBSD core note types.
154 ECase(NT_FREEBSD_THRMISC);
155 ECase(NT_FREEBSD_PROCSTAT_PROC);
156 ECase(NT_FREEBSD_PROCSTAT_FILES);
157 ECase(NT_FREEBSD_PROCSTAT_VMMAP);
158 ECase(NT_FREEBSD_PROCSTAT_GROUPS);
159 ECase(NT_FREEBSD_PROCSTAT_UMASK);
160 ECase(NT_FREEBSD_PROCSTAT_RLIMIT);
161 ECase(NT_FREEBSD_PROCSTAT_OSREL);
162 ECase(NT_FREEBSD_PROCSTAT_PSSTRINGS);
163 ECase(NT_FREEBSD_PROCSTAT_AUXV);
164 // NetBSD core note types.
165 ECase(NT_NETBSDCORE_PROCINFO);
166 ECase(NT_NETBSDCORE_AUXV);
167 ECase(NT_NETBSDCORE_LWPSTATUS);
168 // OpenBSD core note types.
169 ECase(NT_OPENBSD_PROCINFO);
170 ECase(NT_OPENBSD_AUXV);
171 ECase(NT_OPENBSD_REGS);
172 ECase(NT_OPENBSD_FPREGS);
173 ECase(NT_OPENBSD_XFPREGS);
174 ECase(NT_OPENBSD_WCOOKIE);
175 // AMD specific notes. (Code Object V2)
176 ECase(NT_AMD_HSA_CODE_OBJECT_VERSION);
177 ECase(NT_AMD_HSA_HSAIL);
178 ECase(NT_AMD_HSA_ISA_VERSION);
179 ECase(NT_AMD_HSA_METADATA);
180 ECase(NT_AMD_HSA_ISA_NAME);
181 ECase(NT_AMD_PAL_METADATA);
182 // AMDGPU specific notes. (Code Object V3)
183 ECase(NT_AMDGPU_METADATA);
184 // Android specific notes.
185 ECase(NT_ANDROID_TYPE_IDENT);
186 ECase(NT_ANDROID_TYPE_KUSER);
187 ECase(NT_ANDROID_TYPE_MEMTAG);
188#undef ECase
189 IO.enumFallback<Hex32>(Value);
190}
191
192void ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(
193 IO &IO, ELFYAML::ELF_EM &Value) {
194#define ECase(X) IO.enumCase(Value, #X, ELF::X)
195 ECase(EM_NONE);
196 ECase(EM_M32);
197 ECase(EM_SPARC);
198 ECase(EM_386);
199 ECase(EM_68K);
200 ECase(EM_88K);
201 ECase(EM_IAMCU);
202 ECase(EM_860);
203 ECase(EM_MIPS);
204 ECase(EM_S370);
205 ECase(EM_MIPS_RS3_LE);
206 ECase(EM_PARISC);
207 ECase(EM_VPP500);
208 ECase(EM_SPARC32PLUS);
209 ECase(EM_960);
210 ECase(EM_PPC);
211 ECase(EM_PPC64);
212 ECase(EM_S390);
213 ECase(EM_SPU);
214 ECase(EM_V800);
215 ECase(EM_FR20);
216 ECase(EM_RH32);
217 ECase(EM_RCE);
218 ECase(EM_ARM);
219 ECase(EM_ALPHA);
220 ECase(EM_SH);
221 ECase(EM_SPARCV9);
222 ECase(EM_TRICORE);
223 ECase(EM_ARC);
224 ECase(EM_H8_300);
225 ECase(EM_H8_300H);
226 ECase(EM_H8S);
227 ECase(EM_H8_500);
228 ECase(EM_IA_64);
229 ECase(EM_MIPS_X);
230 ECase(EM_COLDFIRE);
231 ECase(EM_68HC12);
232 ECase(EM_MMA);
233 ECase(EM_PCP);
234 ECase(EM_NCPU);
235 ECase(EM_NDR1);
236 ECase(EM_STARCORE);
237 ECase(EM_ME16);
238 ECase(EM_ST100);
239 ECase(EM_TINYJ);
240 ECase(EM_X86_64);
241 ECase(EM_PDSP);
242 ECase(EM_PDP10);
243 ECase(EM_PDP11);
244 ECase(EM_FX66);
245 ECase(EM_ST9PLUS);
246 ECase(EM_ST7);
247 ECase(EM_68HC16);
248 ECase(EM_68HC11);
249 ECase(EM_68HC08);
250 ECase(EM_68HC05);
251 ECase(EM_SVX);
252 ECase(EM_ST19);
253 ECase(EM_VAX);
254 ECase(EM_CRIS);
255 ECase(EM_JAVELIN);
256 ECase(EM_FIREPATH);
257 ECase(EM_ZSP);
258 ECase(EM_MMIX);
259 ECase(EM_HUANY);
260 ECase(EM_PRISM);
261 ECase(EM_AVR);
262 ECase(EM_FR30);
263 ECase(EM_D10V);
264 ECase(EM_D30V);
265 ECase(EM_V850);
266 ECase(EM_M32R);
267 ECase(EM_MN10300);
268 ECase(EM_MN10200);
269 ECase(EM_PJ);
270 ECase(EM_OPENRISC);
271 ECase(EM_ARC_COMPACT);
272 ECase(EM_XTENSA);
273 ECase(EM_VIDEOCORE);
274 ECase(EM_TMM_GPP);
275 ECase(EM_NS32K);
276 ECase(EM_TPC);
277 ECase(EM_SNP1K);
278 ECase(EM_ST200);
279 ECase(EM_IP2K);
280 ECase(EM_MAX);
281 ECase(EM_CR);
282 ECase(EM_F2MC16);
283 ECase(EM_MSP430);
284 ECase(EM_BLACKFIN);
285 ECase(EM_SE_C33);
286 ECase(EM_SEP);
287 ECase(EM_ARCA);
288 ECase(EM_UNICORE);
289 ECase(EM_EXCESS);
290 ECase(EM_DXP);
291 ECase(EM_ALTERA_NIOS2);
292 ECase(EM_CRX);
293 ECase(EM_XGATE);
294 ECase(EM_C166);
295 ECase(EM_M16C);
296 ECase(EM_DSPIC30F);
297 ECase(EM_CE);
298 ECase(EM_M32C);
299 ECase(EM_TSK3000);
300 ECase(EM_RS08);
301 ECase(EM_SHARC);
302 ECase(EM_ECOG2);
303 ECase(EM_SCORE7);
304 ECase(EM_DSP24);
305 ECase(EM_VIDEOCORE3);
306 ECase(EM_LATTICEMICO32);
307 ECase(EM_SE_C17);
308 ECase(EM_TI_C6000);
309 ECase(EM_TI_C2000);
310 ECase(EM_TI_C5500);
311 ECase(EM_MMDSP_PLUS);
312 ECase(EM_CYPRESS_M8C);
313 ECase(EM_R32C);
314 ECase(EM_TRIMEDIA);
315 ECase(EM_HEXAGON);
316 ECase(EM_8051);
317 ECase(EM_STXP7X);
318 ECase(EM_NDS32);
319 ECase(EM_ECOG1);
320 ECase(EM_ECOG1X);
321 ECase(EM_MAXQ30);
322 ECase(EM_XIMO16);
323 ECase(EM_MANIK);
324 ECase(EM_CRAYNV2);
325 ECase(EM_RX);
326 ECase(EM_METAG);
327 ECase(EM_MCST_ELBRUS);
328 ECase(EM_ECOG16);
329 ECase(EM_CR16);
330 ECase(EM_ETPU);
331 ECase(EM_SLE9X);
332 ECase(EM_L10M);
333 ECase(EM_K10M);
334 ECase(EM_AARCH64);
335 ECase(EM_AVR32);
336 ECase(EM_STM8);
337 ECase(EM_TILE64);
338 ECase(EM_TILEPRO);
339 ECase(EM_MICROBLAZE);
340 ECase(EM_CUDA);
341 ECase(EM_TILEGX);
342 ECase(EM_CLOUDSHIELD);
343 ECase(EM_COREA_1ST);
344 ECase(EM_COREA_2ND);
345 ECase(EM_ARC_COMPACT2);
346 ECase(EM_OPEN8);
347 ECase(EM_RL78);
348 ECase(EM_VIDEOCORE5);
349 ECase(EM_78KOR);
350 ECase(EM_56800EX);
351 ECase(EM_AMDGPU);
352 ECase(EM_RISCV);
353 ECase(EM_LANAI);
354 ECase(EM_BPF);
355 ECase(EM_VE);
356 ECase(EM_CSKY);
357 ECase(EM_LOONGARCH);
358#undef ECase
359 IO.enumFallback<Hex16>(Value);
360}
361
362void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration(
363 IO &IO, ELFYAML::ELF_ELFCLASS &Value) {
364#define ECase(X) IO.enumCase(Value, #X, ELF::X)
365 // Since the semantics of ELFCLASSNONE is "invalid", just don't accept it
366 // here.
367 ECase(ELFCLASS32);
368 ECase(ELFCLASS64);
369#undef ECase
370}
371
372void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration(
373 IO &IO, ELFYAML::ELF_ELFDATA &Value) {
374#define ECase(X) IO.enumCase(Value, #X, ELF::X)
375 // ELFDATANONE is an invalid data encoding, but we accept it because
376 // we want to be able to produce invalid binaries for the tests.
377 ECase(ELFDATANONE);
378 ECase(ELFDATA2LSB);
379 ECase(ELFDATA2MSB);
380#undef ECase
381}
382
383void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
384 IO &IO, ELFYAML::ELF_ELFOSABI &Value) {
385#define ECase(X) IO.enumCase(Value, #X, ELF::X)
386 ECase(ELFOSABI_NONE);
387 ECase(ELFOSABI_HPUX);
388 ECase(ELFOSABI_NETBSD);
389 ECase(ELFOSABI_GNU);
390 ECase(ELFOSABI_LINUX);
391 ECase(ELFOSABI_HURD);
392 ECase(ELFOSABI_SOLARIS);
393 ECase(ELFOSABI_AIX);
394 ECase(ELFOSABI_IRIX);
395 ECase(ELFOSABI_FREEBSD);
396 ECase(ELFOSABI_TRU64);
397 ECase(ELFOSABI_MODESTO);
398 ECase(ELFOSABI_OPENBSD);
399 ECase(ELFOSABI_OPENVMS);
400 ECase(ELFOSABI_NSK);
401 ECase(ELFOSABI_AROS);
402 ECase(ELFOSABI_FENIXOS);
403 ECase(ELFOSABI_CLOUDABI);
404 ECase(ELFOSABI_AMDGPU_HSA);
405 ECase(ELFOSABI_AMDGPU_PAL);
406 ECase(ELFOSABI_AMDGPU_MESA3D);
407 ECase(ELFOSABI_ARM);
408 ECase(ELFOSABI_C6000_ELFABI);
409 ECase(ELFOSABI_C6000_LINUX);
410 ECase(ELFOSABI_STANDALONE);
411#undef ECase
412 IO.enumFallback<Hex8>(Value);
413}
414
415void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
416 ELFYAML::ELF_EF &Value) {
417 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
418 assert(Object && "The IO context is not initialized")(static_cast <bool> (Object && "The IO context is not initialized"
) ? void (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 418, __extension__ __PRETTY_FUNCTION__
))
;
419#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
420#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M)
421 switch (Object->getMachine()) {
422 case ELF::EM_ARM:
423 BCase(EF_ARM_SOFT_FLOAT);
424 BCase(EF_ARM_VFP_FLOAT);
425 BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK);
426 BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK);
427 BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK);
428 BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK);
429 BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK);
430 BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK);
431 BCaseMask(EF_ARM_BE8, EF_ARM_BE8);
432 break;
433 case ELF::EM_MIPS:
434 BCase(EF_MIPS_NOREORDER);
435 BCase(EF_MIPS_PIC);
436 BCase(EF_MIPS_CPIC);
437 BCase(EF_MIPS_ABI2);
438 BCase(EF_MIPS_32BITMODE);
439 BCase(EF_MIPS_FP64);
440 BCase(EF_MIPS_NAN2008);
441 BCase(EF_MIPS_MICROMIPS);
442 BCase(EF_MIPS_ARCH_ASE_M16);
443 BCase(EF_MIPS_ARCH_ASE_MDMX);
444 BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI);
445 BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI);
446 BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI);
447 BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI);
448 BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH);
449 BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH);
450 BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH);
451 BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH);
452 BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH);
453 BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH);
454 BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH);
455 BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH);
456 BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH);
457 BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH);
458 BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH);
459 BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH);
460 BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH);
461 BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH);
462 BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH);
463 BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH);
464 BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH);
465 BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH);
466 BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH);
467 BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH);
468 BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH);
469 BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH);
470 BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH);
471 BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH);
472 BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH);
473 BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH);
474 BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH);
475 BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH);
476 BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH);
477 break;
478 case ELF::EM_HEXAGON:
479 BCaseMask(EF_HEXAGON_MACH_V2, EF_HEXAGON_MACH);
480 BCaseMask(EF_HEXAGON_MACH_V3, EF_HEXAGON_MACH);
481 BCaseMask(EF_HEXAGON_MACH_V4, EF_HEXAGON_MACH);
482 BCaseMask(EF_HEXAGON_MACH_V5, EF_HEXAGON_MACH);
483 BCaseMask(EF_HEXAGON_MACH_V55, EF_HEXAGON_MACH);
484 BCaseMask(EF_HEXAGON_MACH_V60, EF_HEXAGON_MACH);
485 BCaseMask(EF_HEXAGON_MACH_V62, EF_HEXAGON_MACH);
486 BCaseMask(EF_HEXAGON_MACH_V65, EF_HEXAGON_MACH);
487 BCaseMask(EF_HEXAGON_MACH_V66, EF_HEXAGON_MACH);
488 BCaseMask(EF_HEXAGON_MACH_V67, EF_HEXAGON_MACH);
489 BCaseMask(EF_HEXAGON_MACH_V67T, EF_HEXAGON_MACH);
490 BCaseMask(EF_HEXAGON_MACH_V68, EF_HEXAGON_MACH);
491 BCaseMask(EF_HEXAGON_MACH_V69, EF_HEXAGON_MACH);
492 BCaseMask(EF_HEXAGON_MACH_V71, EF_HEXAGON_MACH);
493 BCaseMask(EF_HEXAGON_MACH_V71T, EF_HEXAGON_MACH);
494 BCaseMask(EF_HEXAGON_MACH_V73, EF_HEXAGON_MACH);
495 BCaseMask(EF_HEXAGON_ISA_V2, EF_HEXAGON_ISA);
496 BCaseMask(EF_HEXAGON_ISA_V3, EF_HEXAGON_ISA);
497 BCaseMask(EF_HEXAGON_ISA_V4, EF_HEXAGON_ISA);
498 BCaseMask(EF_HEXAGON_ISA_V5, EF_HEXAGON_ISA);
499 BCaseMask(EF_HEXAGON_ISA_V55, EF_HEXAGON_ISA);
500 BCaseMask(EF_HEXAGON_ISA_V60, EF_HEXAGON_ISA);
501 BCaseMask(EF_HEXAGON_ISA_V62, EF_HEXAGON_ISA);
502 BCaseMask(EF_HEXAGON_ISA_V65, EF_HEXAGON_ISA);
503 BCaseMask(EF_HEXAGON_ISA_V66, EF_HEXAGON_ISA);
504 BCaseMask(EF_HEXAGON_ISA_V67, EF_HEXAGON_ISA);
505 BCaseMask(EF_HEXAGON_ISA_V68, EF_HEXAGON_ISA);
506 BCaseMask(EF_HEXAGON_ISA_V69, EF_HEXAGON_ISA);
507 BCaseMask(EF_HEXAGON_ISA_V71, EF_HEXAGON_ISA);
508 BCaseMask(EF_HEXAGON_ISA_V73, EF_HEXAGON_ISA);
509 break;
510 case ELF::EM_AVR:
511 BCaseMask(EF_AVR_ARCH_AVR1, EF_AVR_ARCH_MASK);
512 BCaseMask(EF_AVR_ARCH_AVR2, EF_AVR_ARCH_MASK);
513 BCaseMask(EF_AVR_ARCH_AVR25, EF_AVR_ARCH_MASK);
514 BCaseMask(EF_AVR_ARCH_AVR3, EF_AVR_ARCH_MASK);
515 BCaseMask(EF_AVR_ARCH_AVR31, EF_AVR_ARCH_MASK);
516 BCaseMask(EF_AVR_ARCH_AVR35, EF_AVR_ARCH_MASK);
517 BCaseMask(EF_AVR_ARCH_AVR4, EF_AVR_ARCH_MASK);
518 BCaseMask(EF_AVR_ARCH_AVR5, EF_AVR_ARCH_MASK);
519 BCaseMask(EF_AVR_ARCH_AVR51, EF_AVR_ARCH_MASK);
520 BCaseMask(EF_AVR_ARCH_AVR6, EF_AVR_ARCH_MASK);
521 BCaseMask(EF_AVR_ARCH_AVRTINY, EF_AVR_ARCH_MASK);
522 BCaseMask(EF_AVR_ARCH_XMEGA1, EF_AVR_ARCH_MASK);
523 BCaseMask(EF_AVR_ARCH_XMEGA2, EF_AVR_ARCH_MASK);
524 BCaseMask(EF_AVR_ARCH_XMEGA3, EF_AVR_ARCH_MASK);
525 BCaseMask(EF_AVR_ARCH_XMEGA4, EF_AVR_ARCH_MASK);
526 BCaseMask(EF_AVR_ARCH_XMEGA5, EF_AVR_ARCH_MASK);
527 BCaseMask(EF_AVR_ARCH_XMEGA6, EF_AVR_ARCH_MASK);
528 BCaseMask(EF_AVR_ARCH_XMEGA7, EF_AVR_ARCH_MASK);
529 BCase(EF_AVR_LINKRELAX_PREPARED);
530 break;
531 case ELF::EM_LOONGARCH:
532 BCaseMask(EF_LOONGARCH_ABI_SOFT_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK);
533 BCaseMask(EF_LOONGARCH_ABI_SINGLE_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK);
534 BCaseMask(EF_LOONGARCH_ABI_DOUBLE_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK);
535 BCaseMask(EF_LOONGARCH_OBJABI_V0, EF_LOONGARCH_OBJABI_MASK);
536 BCaseMask(EF_LOONGARCH_OBJABI_V1, EF_LOONGARCH_OBJABI_MASK);
537 break;
538 case ELF::EM_RISCV:
539 BCase(EF_RISCV_RVC);
540 BCaseMask(EF_RISCV_FLOAT_ABI_SOFT, EF_RISCV_FLOAT_ABI);
541 BCaseMask(EF_RISCV_FLOAT_ABI_SINGLE, EF_RISCV_FLOAT_ABI);
542 BCaseMask(EF_RISCV_FLOAT_ABI_DOUBLE, EF_RISCV_FLOAT_ABI);
543 BCaseMask(EF_RISCV_FLOAT_ABI_QUAD, EF_RISCV_FLOAT_ABI);
544 BCase(EF_RISCV_RVE);
545 BCase(EF_RISCV_TSO);
546 break;
547 case ELF::EM_XTENSA:
548 BCase(EF_XTENSA_XT_INSN);
549 BCaseMask(EF_XTENSA_MACH_NONE, EF_XTENSA_MACH);
550 BCase(EF_XTENSA_XT_LIT);
551 break;
552 case ELF::EM_AMDGPU:
553 BCaseMask(EF_AMDGPU_MACH_NONE, EF_AMDGPU_MACH);
554 BCaseMask(EF_AMDGPU_MACH_R600_R600, EF_AMDGPU_MACH);
555 BCaseMask(EF_AMDGPU_MACH_R600_R630, EF_AMDGPU_MACH);
556 BCaseMask(EF_AMDGPU_MACH_R600_RS880, EF_AMDGPU_MACH);
557 BCaseMask(EF_AMDGPU_MACH_R600_RV670, EF_AMDGPU_MACH);
558 BCaseMask(EF_AMDGPU_MACH_R600_RV710, EF_AMDGPU_MACH);
559 BCaseMask(EF_AMDGPU_MACH_R600_RV730, EF_AMDGPU_MACH);
560 BCaseMask(EF_AMDGPU_MACH_R600_RV770, EF_AMDGPU_MACH);
561 BCaseMask(EF_AMDGPU_MACH_R600_CEDAR, EF_AMDGPU_MACH);
562 BCaseMask(EF_AMDGPU_MACH_R600_CYPRESS, EF_AMDGPU_MACH);
563 BCaseMask(EF_AMDGPU_MACH_R600_JUNIPER, EF_AMDGPU_MACH);
564 BCaseMask(EF_AMDGPU_MACH_R600_REDWOOD, EF_AMDGPU_MACH);
565 BCaseMask(EF_AMDGPU_MACH_R600_SUMO, EF_AMDGPU_MACH);
566 BCaseMask(EF_AMDGPU_MACH_R600_BARTS, EF_AMDGPU_MACH);
567 BCaseMask(EF_AMDGPU_MACH_R600_CAICOS, EF_AMDGPU_MACH);
568 BCaseMask(EF_AMDGPU_MACH_R600_CAYMAN, EF_AMDGPU_MACH);
569 BCaseMask(EF_AMDGPU_MACH_R600_TURKS, EF_AMDGPU_MACH);
570 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX600, EF_AMDGPU_MACH);
571 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX601, EF_AMDGPU_MACH);
572 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX602, EF_AMDGPU_MACH);
573 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX700, EF_AMDGPU_MACH);
574 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX701, EF_AMDGPU_MACH);
575 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX702, EF_AMDGPU_MACH);
576 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX703, EF_AMDGPU_MACH);
577 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX704, EF_AMDGPU_MACH);
578 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX705, EF_AMDGPU_MACH);
579 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX801, EF_AMDGPU_MACH);
580 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX802, EF_AMDGPU_MACH);
581 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX803, EF_AMDGPU_MACH);
582 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX805, EF_AMDGPU_MACH);
583 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX810, EF_AMDGPU_MACH);
584 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX900, EF_AMDGPU_MACH);
585 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX902, EF_AMDGPU_MACH);
586 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX904, EF_AMDGPU_MACH);
587 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX906, EF_AMDGPU_MACH);
588 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX908, EF_AMDGPU_MACH);
589 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX909, EF_AMDGPU_MACH);
590 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX90A, EF_AMDGPU_MACH);
591 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX90C, EF_AMDGPU_MACH);
592 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX940, EF_AMDGPU_MACH);
593 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1010, EF_AMDGPU_MACH);
594 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1011, EF_AMDGPU_MACH);
595 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1012, EF_AMDGPU_MACH);
596 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1013, EF_AMDGPU_MACH);
597 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1030, EF_AMDGPU_MACH);
598 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1031, EF_AMDGPU_MACH);
599 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1032, EF_AMDGPU_MACH);
600 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1033, EF_AMDGPU_MACH);
601 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1034, EF_AMDGPU_MACH);
602 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1035, EF_AMDGPU_MACH);
603 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1036, EF_AMDGPU_MACH);
604 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1100, EF_AMDGPU_MACH);
605 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1101, EF_AMDGPU_MACH);
606 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1102, EF_AMDGPU_MACH);
607 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1103, EF_AMDGPU_MACH);
608 switch (Object->Header.ABIVersion) {
609 default:
610 // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags.
611 [[fallthrough]];
612 case ELF::ELFABIVERSION_AMDGPU_HSA_V3:
613 BCase(EF_AMDGPU_FEATURE_XNACK_V3);
614 BCase(EF_AMDGPU_FEATURE_SRAMECC_V3);
615 break;
616 case ELF::ELFABIVERSION_AMDGPU_HSA_V4:
617 case ELF::ELFABIVERSION_AMDGPU_HSA_V5:
618 BCaseMask(EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4,
619 EF_AMDGPU_FEATURE_XNACK_V4);
620 BCaseMask(EF_AMDGPU_FEATURE_XNACK_ANY_V4,
621 EF_AMDGPU_FEATURE_XNACK_V4);
622 BCaseMask(EF_AMDGPU_FEATURE_XNACK_OFF_V4,
623 EF_AMDGPU_FEATURE_XNACK_V4);
624 BCaseMask(EF_AMDGPU_FEATURE_XNACK_ON_V4,
625 EF_AMDGPU_FEATURE_XNACK_V4);
626 BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4,
627 EF_AMDGPU_FEATURE_SRAMECC_V4);
628 BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_ANY_V4,
629 EF_AMDGPU_FEATURE_SRAMECC_V4);
630 BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_OFF_V4,
631 EF_AMDGPU_FEATURE_SRAMECC_V4);
632 BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_ON_V4,
633 EF_AMDGPU_FEATURE_SRAMECC_V4);
634 break;
635 }
636 break;
637 default:
638 break;
639 }
640#undef BCase
641#undef BCaseMask
642}
643
644void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
645 IO &IO, ELFYAML::ELF_SHT &Value) {
646 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
647 assert(Object && "The IO context is not initialized")(static_cast <bool> (Object && "The IO context is not initialized"
) ? void (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 647, __extension__ __PRETTY_FUNCTION__
))
;
13
Assuming 'Object' is non-null
14
'?' condition is true
648#define ECase(X) IO.enumCase(Value, #X, ELF::X)
649 ECase(SHT_NULL);
15
Calling 'IO::enumCase'
20
Returning from 'IO::enumCase'
650 ECase(SHT_PROGBITS);
21
Calling 'IO::enumCase'
26
Returning from 'IO::enumCase'
651 ECase(SHT_SYMTAB);
27
Calling 'IO::enumCase'
32
Returning from 'IO::enumCase'
652 // FIXME: Issue a diagnostic with this information.
653 ECase(SHT_STRTAB);
33
Calling 'IO::enumCase'
38
Returning from 'IO::enumCase'
654 ECase(SHT_RELA);
39
Calling 'IO::enumCase'
44
Returning from 'IO::enumCase'
655 ECase(SHT_HASH);
45
Calling 'IO::enumCase'
50
Returning from 'IO::enumCase'
656 ECase(SHT_DYNAMIC);
51
Calling 'IO::enumCase'
56
Returning from 'IO::enumCase'
657 ECase(SHT_NOTE);
57
Calling 'IO::enumCase'
62
Returning from 'IO::enumCase'
658 ECase(SHT_NOBITS);
63
Calling 'IO::enumCase'
68
Returning from 'IO::enumCase'
659 ECase(SHT_REL);
69
Calling 'IO::enumCase'
74
Returning from 'IO::enumCase'
660 ECase(SHT_SHLIB);
75
Calling 'IO::enumCase'
80
Returning from 'IO::enumCase'
661 ECase(SHT_DYNSYM);
81
Calling 'IO::enumCase'
86
Returning from 'IO::enumCase'
662 ECase(SHT_INIT_ARRAY);
87
Calling 'IO::enumCase'
92
Returning from 'IO::enumCase'
663 ECase(SHT_FINI_ARRAY);
93
Calling 'IO::enumCase'
98
Returning from 'IO::enumCase'
664 ECase(SHT_PREINIT_ARRAY);
99
Calling 'IO::enumCase'
104
Returning from 'IO::enumCase'
665 ECase(SHT_GROUP);
105
Calling 'IO::enumCase'
110
Returning from 'IO::enumCase'
666 ECase(SHT_SYMTAB_SHNDX);
111
Calling 'IO::enumCase'
116
Returning from 'IO::enumCase'
667 ECase(SHT_RELR);
117
Calling 'IO::enumCase'
122
Returning from 'IO::enumCase'
668 ECase(SHT_ANDROID_REL);
123
Calling 'IO::enumCase'
128
Returning from 'IO::enumCase'
669 ECase(SHT_ANDROID_RELA);
129
Calling 'IO::enumCase'
134
Returning from 'IO::enumCase'
670 ECase(SHT_ANDROID_RELR);
135
Calling 'IO::enumCase'
140
Returning from 'IO::enumCase'
671 ECase(SHT_LLVM_ODRTAB);
141
Calling 'IO::enumCase'
146
Returning from 'IO::enumCase'
672 ECase(SHT_LLVM_LINKER_OPTIONS);
147
Calling 'IO::enumCase'
152
Returning from 'IO::enumCase'
673 ECase(SHT_LLVM_CALL_GRAPH_PROFILE);
153
Calling 'IO::enumCase'
158
Returning from 'IO::enumCase'
674 ECase(SHT_LLVM_ADDRSIG);
159
Calling 'IO::enumCase'
164
Returning from 'IO::enumCase'
675 ECase(SHT_LLVM_DEPENDENT_LIBRARIES);
165
Calling 'IO::enumCase'
170
Returning from 'IO::enumCase'
676 ECase(SHT_LLVM_SYMPART);
171
Calling 'IO::enumCase'
176
Returning from 'IO::enumCase'
677 ECase(SHT_LLVM_PART_EHDR);
177
Calling 'IO::enumCase'
182
Returning from 'IO::enumCase'
678 ECase(SHT_LLVM_PART_PHDR);
183
Calling 'IO::enumCase'
188
Returning from 'IO::enumCase'
679 ECase(SHT_LLVM_BB_ADDR_MAP_V0);
189
Calling 'IO::enumCase'
194
Returning from 'IO::enumCase'
680 ECase(SHT_LLVM_BB_ADDR_MAP);
195
Calling 'IO::enumCase'
200
Returning from 'IO::enumCase'
681 ECase(SHT_LLVM_OFFLOADING);
201
Calling 'IO::enumCase'
206
Returning from 'IO::enumCase'
682 ECase(SHT_GNU_ATTRIBUTES);
207
Calling 'IO::enumCase'
212
Returning from 'IO::enumCase'
683 ECase(SHT_GNU_HASH);
213
Calling 'IO::enumCase'
218
Returning from 'IO::enumCase'
684 ECase(SHT_GNU_verdef);
219
Calling 'IO::enumCase'
224
Returning from 'IO::enumCase'
685 ECase(SHT_GNU_verneed);
225
Calling 'IO::enumCase'
230
Returning from 'IO::enumCase'
686 ECase(SHT_GNU_versym);
231
Calling 'IO::enumCase'
236
Returning from 'IO::enumCase'
687 switch (Object->getMachine()) {
237
Control jumps to the 'default' case at line 717
688 case ELF::EM_ARM:
689 ECase(SHT_ARM_EXIDX);
690 ECase(SHT_ARM_PREEMPTMAP);
691 ECase(SHT_ARM_ATTRIBUTES);
692 ECase(SHT_ARM_DEBUGOVERLAY);
693 ECase(SHT_ARM_OVERLAYSECTION);
694 break;
695 case ELF::EM_HEXAGON:
696 ECase(SHT_HEX_ORDERED);
697 break;
698 case ELF::EM_X86_64:
699 ECase(SHT_X86_64_UNWIND);
700 break;
701 case ELF::EM_MIPS:
702 ECase(SHT_MIPS_REGINFO);
703 ECase(SHT_MIPS_OPTIONS);
704 ECase(SHT_MIPS_DWARF);
705 ECase(SHT_MIPS_ABIFLAGS);
706 break;
707 case ELF::EM_RISCV:
708 ECase(SHT_RISCV_ATTRIBUTES);
709 break;
710 case ELF::EM_MSP430:
711 ECase(SHT_MSP430_ATTRIBUTES);
712 break;
713 case ELF::EM_AARCH64:
714 ECase(SHT_AARCH64_MEMTAG_GLOBALS_STATIC);
715 ECase(SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC);
716 break;
717 default:
718 // Nothing to do.
719 break;
238
Execution continues on line 722
720 }
721#undef ECase
722 IO.enumFallback<Hex32>(Value);
239
Calling 'IO::enumFallback'
723}
724
725void ScalarBitSetTraits<ELFYAML::ELF_PF>::bitset(IO &IO,
726 ELFYAML::ELF_PF &Value) {
727#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
728 BCase(PF_X);
729 BCase(PF_W);
730 BCase(PF_R);
731}
732
733void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
734 ELFYAML::ELF_SHF &Value) {
735 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
736#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
737 BCase(SHF_WRITE);
738 BCase(SHF_ALLOC);
739 BCase(SHF_EXCLUDE);
740 BCase(SHF_EXECINSTR);
741 BCase(SHF_MERGE);
742 BCase(SHF_STRINGS);
743 BCase(SHF_INFO_LINK);
744 BCase(SHF_LINK_ORDER);
745 BCase(SHF_OS_NONCONFORMING);
746 BCase(SHF_GROUP);
747 BCase(SHF_TLS);
748 BCase(SHF_COMPRESSED);
749 switch (Object->getOSAbi()) {
750 case ELF::ELFOSABI_SOLARIS:
751 BCase(SHF_SUNW_NODISCARD);
752 break;
753 default:
754 BCase(SHF_GNU_RETAIN);
755 break;
756 }
757 switch (Object->getMachine()) {
758 case ELF::EM_ARM:
759 BCase(SHF_ARM_PURECODE);
760 break;
761 case ELF::EM_HEXAGON:
762 BCase(SHF_HEX_GPREL);
763 break;
764 case ELF::EM_MIPS:
765 BCase(SHF_MIPS_NODUPES);
766 BCase(SHF_MIPS_NAMES);
767 BCase(SHF_MIPS_LOCAL);
768 BCase(SHF_MIPS_NOSTRIP);
769 BCase(SHF_MIPS_GPREL);
770 BCase(SHF_MIPS_MERGE);
771 BCase(SHF_MIPS_ADDR);
772 BCase(SHF_MIPS_STRING);
773 break;
774 case ELF::EM_X86_64:
775 BCase(SHF_X86_64_LARGE);
776 break;
777 default:
778 // Nothing to do.
779 break;
780 }
781#undef BCase
782}
783
784void ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration(
785 IO &IO, ELFYAML::ELF_SHN &Value) {
786 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
787 assert(Object && "The IO context is not initialized")(static_cast <bool> (Object && "The IO context is not initialized"
) ? void (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 787, __extension__ __PRETTY_FUNCTION__
))
;
788#define ECase(X) IO.enumCase(Value, #X, ELF::X)
789 ECase(SHN_UNDEF);
790 ECase(SHN_LORESERVE);
791 ECase(SHN_LOPROC);
792 ECase(SHN_HIPROC);
793 ECase(SHN_LOOS);
794 ECase(SHN_HIOS);
795 ECase(SHN_ABS);
796 ECase(SHN_COMMON);
797 ECase(SHN_XINDEX);
798 ECase(SHN_HIRESERVE);
799 ECase(SHN_AMDGPU_LDS);
800
801 if (!IO.outputting() || Object->getMachine() == ELF::EM_MIPS) {
802 ECase(SHN_MIPS_ACOMMON);
803 ECase(SHN_MIPS_TEXT);
804 ECase(SHN_MIPS_DATA);
805 ECase(SHN_MIPS_SCOMMON);
806 ECase(SHN_MIPS_SUNDEFINED);
807 }
808
809 ECase(SHN_HEXAGON_SCOMMON);
810 ECase(SHN_HEXAGON_SCOMMON_1);
811 ECase(SHN_HEXAGON_SCOMMON_2);
812 ECase(SHN_HEXAGON_SCOMMON_4);
813 ECase(SHN_HEXAGON_SCOMMON_8);
814#undef ECase
815 IO.enumFallback<Hex16>(Value);
816}
817
818void ScalarEnumerationTraits<ELFYAML::ELF_STB>::enumeration(
819 IO &IO, ELFYAML::ELF_STB &Value) {
820#define ECase(X) IO.enumCase(Value, #X, ELF::X)
821 ECase(STB_LOCAL);
822 ECase(STB_GLOBAL);
823 ECase(STB_WEAK);
824 ECase(STB_GNU_UNIQUE);
825#undef ECase
826 IO.enumFallback<Hex8>(Value);
827}
828
829void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
830 IO &IO, ELFYAML::ELF_STT &Value) {
831#define ECase(X) IO.enumCase(Value, #X, ELF::X)
832 ECase(STT_NOTYPE);
833 ECase(STT_OBJECT);
834 ECase(STT_FUNC);
835 ECase(STT_SECTION);
836 ECase(STT_FILE);
837 ECase(STT_COMMON);
838 ECase(STT_TLS);
839 ECase(STT_GNU_IFUNC);
840#undef ECase
841 IO.enumFallback<Hex8>(Value);
842}
843
844
845void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration(
846 IO &IO, ELFYAML::ELF_RSS &Value) {
847#define ECase(X) IO.enumCase(Value, #X, ELF::X)
848 ECase(RSS_UNDEF);
849 ECase(RSS_GP);
850 ECase(RSS_GP0);
851 ECase(RSS_LOC);
852#undef ECase
853}
854
855void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
856 IO &IO, ELFYAML::ELF_REL &Value) {
857 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
858 assert(Object && "The IO context is not initialized")(static_cast <bool> (Object && "The IO context is not initialized"
) ? void (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 858, __extension__ __PRETTY_FUNCTION__
))
;
859#define ELF_RELOC(X, Y) IO.enumCase(Value, #X, ELF::X);
860 switch (Object->getMachine()) {
861 case ELF::EM_X86_64:
862#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
863 break;
864 case ELF::EM_MIPS:
865#include "llvm/BinaryFormat/ELFRelocs/Mips.def"
866 break;
867 case ELF::EM_HEXAGON:
868#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
869 break;
870 case ELF::EM_386:
871 case ELF::EM_IAMCU:
872#include "llvm/BinaryFormat/ELFRelocs/i386.def"
873 break;
874 case ELF::EM_AARCH64:
875#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
876 break;
877 case ELF::EM_ARM:
878#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
879 break;
880 case ELF::EM_ARC:
881#include "llvm/BinaryFormat/ELFRelocs/ARC.def"
882 break;
883 case ELF::EM_RISCV:
884#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
885 break;
886 case ELF::EM_LANAI:
887#include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
888 break;
889 case ELF::EM_AMDGPU:
890#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
891 break;
892 case ELF::EM_BPF:
893#include "llvm/BinaryFormat/ELFRelocs/BPF.def"
894 break;
895 case ELF::EM_VE:
896#include "llvm/BinaryFormat/ELFRelocs/VE.def"
897 break;
898 case ELF::EM_CSKY:
899#include "llvm/BinaryFormat/ELFRelocs/CSKY.def"
900 break;
901 case ELF::EM_PPC:
902#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
903 break;
904 case ELF::EM_PPC64:
905#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
906 break;
907 case ELF::EM_68K:
908#include "llvm/BinaryFormat/ELFRelocs/M68k.def"
909 break;
910 case ELF::EM_LOONGARCH:
911#include "llvm/BinaryFormat/ELFRelocs/LoongArch.def"
912 break;
913 case ELF::EM_XTENSA:
914#include "llvm/BinaryFormat/ELFRelocs/Xtensa.def"
915 break;
916 default:
917 // Nothing to do.
918 break;
919 }
920#undef ELF_RELOC
921 IO.enumFallback<Hex32>(Value);
922}
923
924void ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG>::enumeration(
925 IO &IO, ELFYAML::ELF_DYNTAG &Value) {
926 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
927 assert(Object && "The IO context is not initialized")(static_cast <bool> (Object && "The IO context is not initialized"
) ? void (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 927, __extension__ __PRETTY_FUNCTION__
))
;
928
929// Disable architecture specific tags by default. We might enable them below.
930#define AARCH64_DYNAMIC_TAG(name, value)
931#define MIPS_DYNAMIC_TAG(name, value)
932#define HEXAGON_DYNAMIC_TAG(name, value)
933#define PPC_DYNAMIC_TAG(name, value)
934#define PPC64_DYNAMIC_TAG(name, value)
935// Ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
936#define DYNAMIC_TAG_MARKER(name, value)
937
938#define STRINGIFY(X) (#X)
939#define DYNAMIC_TAG(X, Y) IO.enumCase(Value, STRINGIFY(DT_##X), ELF::DT_##X);
940 switch (Object->getMachine()) {
941 case ELF::EM_AARCH64:
942#undef AARCH64_DYNAMIC_TAG
943#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
944#include "llvm/BinaryFormat/DynamicTags.def"
945#undef AARCH64_DYNAMIC_TAG
946#define AARCH64_DYNAMIC_TAG(name, value)
947 break;
948 case ELF::EM_MIPS:
949#undef MIPS_DYNAMIC_TAG
950#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
951#include "llvm/BinaryFormat/DynamicTags.def"
952#undef MIPS_DYNAMIC_TAG
953#define MIPS_DYNAMIC_TAG(name, value)
954 break;
955 case ELF::EM_HEXAGON:
956#undef HEXAGON_DYNAMIC_TAG
957#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
958#include "llvm/BinaryFormat/DynamicTags.def"
959#undef HEXAGON_DYNAMIC_TAG
960#define HEXAGON_DYNAMIC_TAG(name, value)
961 break;
962 case ELF::EM_PPC:
963#undef PPC_DYNAMIC_TAG
964#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
965#include "llvm/BinaryFormat/DynamicTags.def"
966#undef PPC_DYNAMIC_TAG
967#define PPC_DYNAMIC_TAG(name, value)
968 break;
969 case ELF::EM_PPC64:
970#undef PPC64_DYNAMIC_TAG
971#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
972#include "llvm/BinaryFormat/DynamicTags.def"
973#undef PPC64_DYNAMIC_TAG
974#define PPC64_DYNAMIC_TAG(name, value)
975 break;
976 case ELF::EM_RISCV:
977#undef RISCV_DYNAMIC_TAG
978#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
979#include "llvm/BinaryFormat/DynamicTags.def"
980#undef RISCV_DYNAMIC_TAG
981#define RISCV_DYNAMIC_TAG(name, value)
982 break;
983 default:
984#include "llvm/BinaryFormat/DynamicTags.def"
985 break;
986 }
987#undef AARCH64_DYNAMIC_TAG
988#undef MIPS_DYNAMIC_TAG
989#undef HEXAGON_DYNAMIC_TAG
990#undef PPC_DYNAMIC_TAG
991#undef PPC64_DYNAMIC_TAG
992#undef DYNAMIC_TAG_MARKER
993#undef STRINGIFY
994#undef DYNAMIC_TAG
995
996 IO.enumFallback<Hex64>(Value);
997}
998
999void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration(
1000 IO &IO, ELFYAML::MIPS_AFL_REG &Value) {
1001#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X)
1002 ECase(REG_NONE);
1003 ECase(REG_32);
1004 ECase(REG_64);
1005 ECase(REG_128);
1006#undef ECase
1007}
1008
1009void ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP>::enumeration(
1010 IO &IO, ELFYAML::MIPS_ABI_FP &Value) {
1011#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X)
1012 ECase(FP_ANY);
1013 ECase(FP_DOUBLE);
1014 ECase(FP_SINGLE);
1015 ECase(FP_SOFT);
1016 ECase(FP_OLD_64);
1017 ECase(FP_XX);
1018 ECase(FP_64);
1019 ECase(FP_64A);
1020#undef ECase
1021}
1022
1023void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT>::enumeration(
1024 IO &IO, ELFYAML::MIPS_AFL_EXT &Value) {
1025#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X)
1026 ECase(EXT_NONE);
1027 ECase(EXT_XLR);
1028 ECase(EXT_OCTEON2);
1029 ECase(EXT_OCTEONP);
1030 ECase(EXT_LOONGSON_3A);
1031 ECase(EXT_OCTEON);
1032 ECase(EXT_5900);
1033 ECase(EXT_4650);
1034 ECase(EXT_4010);
1035 ECase(EXT_4100);
1036 ECase(EXT_3900);
1037 ECase(EXT_10000);
1038 ECase(EXT_SB1);
1039 ECase(EXT_4111);
1040 ECase(EXT_4120);
1041 ECase(EXT_5400);
1042 ECase(EXT_5500);
1043 ECase(EXT_LOONGSON_2E);
1044 ECase(EXT_LOONGSON_2F);
1045 ECase(EXT_OCTEON3);
1046#undef ECase
1047}
1048
1049void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration(
1050 IO &IO, ELFYAML::MIPS_ISA &Value) {
1051 IO.enumCase(Value, "MIPS1", 1);
1052 IO.enumCase(Value, "MIPS2", 2);
1053 IO.enumCase(Value, "MIPS3", 3);
1054 IO.enumCase(Value, "MIPS4", 4);
1055 IO.enumCase(Value, "MIPS5", 5);
1056 IO.enumCase(Value, "MIPS32", 32);
1057 IO.enumCase(Value, "MIPS64", 64);
1058 IO.enumFallback<Hex32>(Value);
1059}
1060
1061void ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE>::bitset(
1062 IO &IO, ELFYAML::MIPS_AFL_ASE &Value) {
1063#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X)
1064 BCase(DSP);
1065 BCase(DSPR2);
1066 BCase(EVA);
1067 BCase(MCU);
1068 BCase(MDMX);
1069 BCase(MIPS3D);
1070 BCase(MT);
1071 BCase(SMARTMIPS);
1072 BCase(VIRT);
1073 BCase(MSA);
1074 BCase(MIPS16);
1075 BCase(MICROMIPS);
1076 BCase(XPA);
1077 BCase(CRC);
1078 BCase(GINV);
1079#undef BCase
1080}
1081
1082void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset(
1083 IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value) {
1084#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X)
1085 BCase(ODDSPREG);
1086#undef BCase
1087}
1088
1089void MappingTraits<ELFYAML::SectionHeader>::mapping(
1090 IO &IO, ELFYAML::SectionHeader &SHdr) {
1091 IO.mapRequired("Name", SHdr.Name);
1092}
1093
1094void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
1095 ELFYAML::FileHeader &FileHdr) {
1096 IO.mapRequired("Class", FileHdr.Class);
1097 IO.mapRequired("Data", FileHdr.Data);
1098 IO.mapOptional("OSABI", FileHdr.OSABI, ELFYAML::ELF_ELFOSABI(0));
1099 IO.mapOptional("ABIVersion", FileHdr.ABIVersion, Hex8(0));
1100 IO.mapRequired("Type", FileHdr.Type);
1101 IO.mapOptional("Machine", FileHdr.Machine);
1102 IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
1103 IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
1104 IO.mapOptional("SectionHeaderStringTable", FileHdr.SectionHeaderStringTable);
1105
1106 // obj2yaml does not dump these fields.
1107 assert(!IO.outputting() ||(static_cast <bool> (!IO.outputting() || (!FileHdr.EPhOff
&& !FileHdr.EPhEntSize && !FileHdr.EPhNum)) ?
void (0) : __assert_fail ("!IO.outputting() || (!FileHdr.EPhOff && !FileHdr.EPhEntSize && !FileHdr.EPhNum)"
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1108, __extension__ __PRETTY_FUNCTION__
))
1108 (!FileHdr.EPhOff && !FileHdr.EPhEntSize && !FileHdr.EPhNum))(static_cast <bool> (!IO.outputting() || (!FileHdr.EPhOff
&& !FileHdr.EPhEntSize && !FileHdr.EPhNum)) ?
void (0) : __assert_fail ("!IO.outputting() || (!FileHdr.EPhOff && !FileHdr.EPhEntSize && !FileHdr.EPhNum)"
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1108, __extension__ __PRETTY_FUNCTION__
))
;
1109 IO.mapOptional("EPhOff", FileHdr.EPhOff);
1110 IO.mapOptional("EPhEntSize", FileHdr.EPhEntSize);
1111 IO.mapOptional("EPhNum", FileHdr.EPhNum);
1112 IO.mapOptional("EShEntSize", FileHdr.EShEntSize);
1113 IO.mapOptional("EShOff", FileHdr.EShOff);
1114 IO.mapOptional("EShNum", FileHdr.EShNum);
1115 IO.mapOptional("EShStrNdx", FileHdr.EShStrNdx);
1116}
1117
1118void MappingTraits<ELFYAML::ProgramHeader>::mapping(
1119 IO &IO, ELFYAML::ProgramHeader &Phdr) {
1120 IO.mapRequired("Type", Phdr.Type);
1121 IO.mapOptional("Flags", Phdr.Flags, ELFYAML::ELF_PF(0));
1122 IO.mapOptional("FirstSec", Phdr.FirstSec);
1123 IO.mapOptional("LastSec", Phdr.LastSec);
1124 IO.mapOptional("VAddr", Phdr.VAddr, Hex64(0));
1125 IO.mapOptional("PAddr", Phdr.PAddr, Phdr.VAddr);
1126 IO.mapOptional("Align", Phdr.Align);
1127 IO.mapOptional("FileSize", Phdr.FileSize);
1128 IO.mapOptional("MemSize", Phdr.MemSize);
1129 IO.mapOptional("Offset", Phdr.Offset);
1130}
1131
1132std::string MappingTraits<ELFYAML::ProgramHeader>::validate(
1133 IO &IO, ELFYAML::ProgramHeader &FileHdr) {
1134 if (!FileHdr.FirstSec && FileHdr.LastSec)
1135 return "the \"LastSec\" key can't be used without the \"FirstSec\" key";
1136 if (FileHdr.FirstSec && !FileHdr.LastSec)
1137 return "the \"FirstSec\" key can't be used without the \"LastSec\" key";
1138 return "";
1139}
1140
1141LLVM_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
; };
1142
1143template <> struct ScalarTraits<StOtherPiece> {
1144 static void output(const StOtherPiece &Val, void *, raw_ostream &Out) {
1145 Out << Val;
1146 }
1147 static StringRef input(StringRef Scalar, void *, StOtherPiece &Val) {
1148 Val = Scalar;
1149 return {};
1150 }
1151 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1152};
1153template <> struct SequenceElementTraits<StOtherPiece> {
1154 static const bool flow = true;
1155};
1156
1157template <> struct ScalarTraits<ELFYAML::YAMLFlowString> {
1158 static void output(const ELFYAML::YAMLFlowString &Val, void *,
1159 raw_ostream &Out) {
1160 Out << Val;
1161 }
1162 static StringRef input(StringRef Scalar, void *,
1163 ELFYAML::YAMLFlowString &Val) {
1164 Val = Scalar;
1165 return {};
1166 }
1167 static QuotingType mustQuote(StringRef S) {
1168 return ScalarTraits<StringRef>::mustQuote(S);
1169 }
1170};
1171template <> struct SequenceElementTraits<ELFYAML::YAMLFlowString> {
1172 static const bool flow = true;
1173};
1174
1175namespace {
1176
1177struct NormalizedOther {
1178 NormalizedOther(IO &IO) : YamlIO(IO) {}
1179 NormalizedOther(IO &IO, std::optional<uint8_t> Original) : YamlIO(IO) {
1180 assert(Original && "This constructor is only used for outputting YAML and "(static_cast <bool> (Original && "This constructor is only used for outputting YAML and "
"assumes a non-empty Original") ? void (0) : __assert_fail (
"Original && \"This constructor is only used for outputting YAML and \" \"assumes a non-empty Original\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1181, __extension__ __PRETTY_FUNCTION__
))
1181 "assumes a non-empty Original")(static_cast <bool> (Original && "This constructor is only used for outputting YAML and "
"assumes a non-empty Original") ? void (0) : __assert_fail (
"Original && \"This constructor is only used for outputting YAML and \" \"assumes a non-empty Original\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1181, __extension__ __PRETTY_FUNCTION__
))
;
1182 std::vector<StOtherPiece> Ret;
1183 const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext());
1184 for (std::pair<StringRef, uint8_t> &P :
1185 getFlags(Object->getMachine()).takeVector()) {
1186 uint8_t FlagValue = P.second;
1187 if ((*Original & FlagValue) != FlagValue)
1188 continue;
1189 *Original &= ~FlagValue;
1190 Ret.push_back({P.first});
1191 }
1192
1193 if (*Original != 0) {
1194 UnknownFlagsHolder = std::to_string(*Original);
1195 Ret.push_back({UnknownFlagsHolder});
1196 }
1197
1198 if (!Ret.empty())
1199 Other = std::move(Ret);
1200 }
1201
1202 uint8_t toValue(StringRef Name) {
1203 const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext());
1204 MapVector<StringRef, uint8_t> Flags = getFlags(Object->getMachine());
1205
1206 auto It = Flags.find(Name);
1207 if (It != Flags.end())
1208 return It->second;
1209
1210 uint8_t Val;
1211 if (to_integer(Name, Val))
1212 return Val;
1213
1214 YamlIO.setError("an unknown value is used for symbol's 'Other' field: " +
1215 Name);
1216 return 0;
1217 }
1218
1219 std::optional<uint8_t> denormalize(IO &) {
1220 if (!Other)
1221 return std::nullopt;
1222 uint8_t Ret = 0;
1223 for (StOtherPiece &Val : *Other)
1224 Ret |= toValue(Val);
1225 return Ret;
1226 }
1227
1228 // st_other field is used to encode symbol visibility and platform-dependent
1229 // flags and values. This method returns a name to value map that is used for
1230 // parsing and encoding this field.
1231 MapVector<StringRef, uint8_t> getFlags(unsigned EMachine) {
1232 MapVector<StringRef, uint8_t> Map;
1233 // STV_* values are just enumeration values. We add them in a reversed order
1234 // because when we convert the st_other to named constants when printing
1235 // YAML we want to use a maximum number of bits on each step:
1236 // when we have st_other == 3, we want to print it as STV_PROTECTED (3), but
1237 // not as STV_HIDDEN (2) + STV_INTERNAL (1).
1238 Map["STV_PROTECTED"] = ELF::STV_PROTECTED;
1239 Map["STV_HIDDEN"] = ELF::STV_HIDDEN;
1240 Map["STV_INTERNAL"] = ELF::STV_INTERNAL;
1241 // STV_DEFAULT is used to represent the default visibility and has a value
1242 // 0. We want to be able to read it from YAML documents, but there is no
1243 // reason to print it.
1244 if (!YamlIO.outputting())
1245 Map["STV_DEFAULT"] = ELF::STV_DEFAULT;
1246
1247 // MIPS is not consistent. All of the STO_MIPS_* values are bit flags,
1248 // except STO_MIPS_MIPS16 which overlaps them. It should be checked and
1249 // consumed first when we print the output, because we do not want to print
1250 // any other flags that have the same bits instead.
1251 if (EMachine == ELF::EM_MIPS) {
1252 Map["STO_MIPS_MIPS16"] = ELF::STO_MIPS_MIPS16;
1253 Map["STO_MIPS_MICROMIPS"] = ELF::STO_MIPS_MICROMIPS;
1254 Map["STO_MIPS_PIC"] = ELF::STO_MIPS_PIC;
1255 Map["STO_MIPS_PLT"] = ELF::STO_MIPS_PLT;
1256 Map["STO_MIPS_OPTIONAL"] = ELF::STO_MIPS_OPTIONAL;
1257 }
1258
1259 if (EMachine == ELF::EM_AARCH64)
1260 Map["STO_AARCH64_VARIANT_PCS"] = ELF::STO_AARCH64_VARIANT_PCS;
1261 if (EMachine == ELF::EM_RISCV)
1262 Map["STO_RISCV_VARIANT_CC"] = ELF::STO_RISCV_VARIANT_CC;
1263 return Map;
1264 }
1265
1266 IO &YamlIO;
1267 std::optional<std::vector<StOtherPiece>> Other;
1268 std::string UnknownFlagsHolder;
1269};
1270
1271} // end anonymous namespace
1272
1273void ScalarTraits<ELFYAML::YAMLIntUInt>::output(const ELFYAML::YAMLIntUInt &Val,
1274 void *Ctx, raw_ostream &Out) {
1275 Out << Val;
1276}
1277
1278StringRef ScalarTraits<ELFYAML::YAMLIntUInt>::input(StringRef Scalar, void *Ctx,
1279 ELFYAML::YAMLIntUInt &Val) {
1280 const bool Is64 = static_cast<ELFYAML::Object *>(Ctx)->Header.Class ==
1281 ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
1282 StringRef ErrMsg = "invalid number";
1283 // We do not accept negative hex numbers because their meaning is ambiguous.
1284 // For example, would -0xfffffffff mean 1 or INT32_MIN?
1285 if (Scalar.empty() || Scalar.startswith("-0x"))
1286 return ErrMsg;
1287
1288 if (Scalar.startswith("-")) {
1289 const int64_t MinVal = Is64 ? INT64_MIN(-9223372036854775807L -1) : INT32_MIN(-2147483647-1);
1290 long long Int;
1291 if (getAsSignedInteger(Scalar, /*Radix=*/0, Int) || (Int < MinVal))
1292 return ErrMsg;
1293 Val = Int;
1294 return "";
1295 }
1296
1297 const uint64_t MaxVal = Is64 ? UINT64_MAX(18446744073709551615UL) : UINT32_MAX(4294967295U);
1298 unsigned long long UInt;
1299 if (getAsUnsignedInteger(Scalar, /*Radix=*/0, UInt) || (UInt > MaxVal))
1300 return ErrMsg;
1301 Val = UInt;
1302 return "";
1303}
1304
1305void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
1306 IO.mapOptional("Name", Symbol.Name, StringRef());
1307 IO.mapOptional("StName", Symbol.StName);
1308 IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
1309 IO.mapOptional("Section", Symbol.Section);
1310 IO.mapOptional("Index", Symbol.Index);
1311 IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0));
1312 IO.mapOptional("Value", Symbol.Value);
1313 IO.mapOptional("Size", Symbol.Size);
1314
1315 // Symbol's Other field is a bit special. It is usually a field that
1316 // represents st_other and holds the symbol visibility. However, on some
1317 // platforms, it can contain bit fields and regular values, or even sometimes
1318 // a crazy mix of them (see comments for NormalizedOther). Because of this, we
1319 // need special handling.
1320 MappingNormalization<NormalizedOther, std::optional<uint8_t>> Keys(
1321 IO, Symbol.Other);
1322 IO.mapOptional("Other", Keys->Other);
1323}
1324
1325std::string MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
1326 ELFYAML::Symbol &Symbol) {
1327 if (Symbol.Index && Symbol.Section)
1328 return "Index and Section cannot both be specified for Symbol";
1329 return "";
1330}
1331
1332static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
1333 IO.mapOptional("Name", Section.Name, StringRef());
1334 IO.mapRequired("Type", Section.Type);
1335 IO.mapOptional("Flags", Section.Flags);
1336 IO.mapOptional("Address", Section.Address);
1337 IO.mapOptional("Link", Section.Link);
1338 IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
1339 IO.mapOptional("EntSize", Section.EntSize);
1340 IO.mapOptional("Offset", Section.Offset);
1341
1342 IO.mapOptional("Content", Section.Content);
1343 IO.mapOptional("Size", Section.Size);
1344
1345 // obj2yaml does not dump these fields. They are expected to be empty when we
1346 // are producing YAML, because yaml2obj sets appropriate values for them
1347 // automatically when they are not explicitly defined.
1348 assert(!IO.outputting() ||(static_cast <bool> (!IO.outputting() || (!Section.ShOffset
&& !Section.ShSize && !Section.ShName &&
!Section.ShFlags && !Section.ShType && !Section
.ShAddrAlign)) ? void (0) : __assert_fail ("!IO.outputting() || (!Section.ShOffset && !Section.ShSize && !Section.ShName && !Section.ShFlags && !Section.ShType && !Section.ShAddrAlign)"
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1350, __extension__ __PRETTY_FUNCTION__
))
1349 (!Section.ShOffset && !Section.ShSize && !Section.ShName &&(static_cast <bool> (!IO.outputting() || (!Section.ShOffset
&& !Section.ShSize && !Section.ShName &&
!Section.ShFlags && !Section.ShType && !Section
.ShAddrAlign)) ? void (0) : __assert_fail ("!IO.outputting() || (!Section.ShOffset && !Section.ShSize && !Section.ShName && !Section.ShFlags && !Section.ShType && !Section.ShAddrAlign)"
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1350, __extension__ __PRETTY_FUNCTION__
))
1350 !Section.ShFlags && !Section.ShType && !Section.ShAddrAlign))(static_cast <bool> (!IO.outputting() || (!Section.ShOffset
&& !Section.ShSize && !Section.ShName &&
!Section.ShFlags && !Section.ShType && !Section
.ShAddrAlign)) ? void (0) : __assert_fail ("!IO.outputting() || (!Section.ShOffset && !Section.ShSize && !Section.ShName && !Section.ShFlags && !Section.ShType && !Section.ShAddrAlign)"
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1350, __extension__ __PRETTY_FUNCTION__
))
;
1351 IO.mapOptional("ShAddrAlign", Section.ShAddrAlign);
1352 IO.mapOptional("ShName", Section.ShName);
1353 IO.mapOptional("ShOffset", Section.ShOffset);
1354 IO.mapOptional("ShSize", Section.ShSize);
1355 IO.mapOptional("ShFlags", Section.ShFlags);
1356 IO.mapOptional("ShType", Section.ShType);
1357}
1358
1359static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
1360 commonSectionMapping(IO, Section);
1361 IO.mapOptional("Entries", Section.Entries);
1362}
1363
1364static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
1365 commonSectionMapping(IO, Section);
1366
1367 // We also support reading a content as array of bytes using the ContentArray
1368 // key. obj2yaml never prints this field.
1369 assert(!IO.outputting() || !Section.ContentBuf)(static_cast <bool> (!IO.outputting() || !Section.ContentBuf
) ? void (0) : __assert_fail ("!IO.outputting() || !Section.ContentBuf"
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1369, __extension__ __PRETTY_FUNCTION__
))
;
1370 IO.mapOptional("ContentArray", Section.ContentBuf);
1371 if (Section.ContentBuf) {
1372 if (Section.Content)
1373 IO.setError("Content and ContentArray can't be used together");
1374 Section.Content = yaml::BinaryRef(*Section.ContentBuf);
1375 }
1376
1377 IO.mapOptional("Info", Section.Info);
1378}
1379
1380static void sectionMapping(IO &IO, ELFYAML::BBAddrMapSection &Section) {
1381 commonSectionMapping(IO, Section);
1382 IO.mapOptional("Content", Section.Content);
1383 IO.mapOptional("Entries", Section.Entries);
1384}
1385
1386static void sectionMapping(IO &IO, ELFYAML::StackSizesSection &Section) {
1387 commonSectionMapping(IO, Section);
1388 IO.mapOptional("Entries", Section.Entries);
1389}
1390
1391static void sectionMapping(IO &IO, ELFYAML::HashSection &Section) {
1392 commonSectionMapping(IO, Section);
1393 IO.mapOptional("Bucket", Section.Bucket);
1394 IO.mapOptional("Chain", Section.Chain);
1395
1396 // obj2yaml does not dump these fields. They can be used to override nchain
1397 // and nbucket values for creating broken sections.
1398 assert(!IO.outputting() || (!Section.NBucket && !Section.NChain))(static_cast <bool> (!IO.outputting() || (!Section.NBucket
&& !Section.NChain)) ? void (0) : __assert_fail ("!IO.outputting() || (!Section.NBucket && !Section.NChain)"
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1398, __extension__ __PRETTY_FUNCTION__
))
;
1399 IO.mapOptional("NChain", Section.NChain);
1400 IO.mapOptional("NBucket", Section.NBucket);
1401}
1402
1403static void sectionMapping(IO &IO, ELFYAML::NoteSection &Section) {
1404 commonSectionMapping(IO, Section);
1405 IO.mapOptional("Notes", Section.Notes);
1406}
1407
1408
1409static void sectionMapping(IO &IO, ELFYAML::GnuHashSection &Section) {
1410 commonSectionMapping(IO, Section);
1411 IO.mapOptional("Header", Section.Header);
1412 IO.mapOptional("BloomFilter", Section.BloomFilter);
1413 IO.mapOptional("HashBuckets", Section.HashBuckets);
1414 IO.mapOptional("HashValues", Section.HashValues);
1415}
1416static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
1417 commonSectionMapping(IO, Section);
1418}
1419
1420static void sectionMapping(IO &IO, ELFYAML::VerdefSection &Section) {
1421 commonSectionMapping(IO, Section);
1422 IO.mapOptional("Info", Section.Info);
1423 IO.mapOptional("Entries", Section.Entries);
1424}
1425
1426static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
1427 commonSectionMapping(IO, Section);
1428 IO.mapOptional("Entries", Section.Entries);
1429}
1430
1431static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) {
1432 commonSectionMapping(IO, Section);
1433 IO.mapOptional("Info", Section.Info);
1434 IO.mapOptional("Dependencies", Section.VerneedV);
1435}
1436
1437static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
1438 commonSectionMapping(IO, Section);
1439 IO.mapOptional("Info", Section.RelocatableSec, StringRef());
1440 IO.mapOptional("Relocations", Section.Relocations);
1441}
1442
1443static void sectionMapping(IO &IO, ELFYAML::RelrSection &Section) {
1444 commonSectionMapping(IO, Section);
1445 IO.mapOptional("Entries", Section.Entries);
1446}
1447
1448static void groupSectionMapping(IO &IO, ELFYAML::GroupSection &Group) {
1449 commonSectionMapping(IO, Group);
1450 IO.mapOptional("Info", Group.Signature);
1451 IO.mapOptional("Members", Group.Members);
1452}
1453
1454static void sectionMapping(IO &IO, ELFYAML::SymtabShndxSection &Section) {
1455 commonSectionMapping(IO, Section);
1456 IO.mapOptional("Entries", Section.Entries);
1457}
1458
1459static void sectionMapping(IO &IO, ELFYAML::AddrsigSection &Section) {
1460 commonSectionMapping(IO, Section);
1461 IO.mapOptional("Symbols", Section.Symbols);
1462}
1463
1464static void fillMapping(IO &IO, ELFYAML::Fill &Fill) {
1465 IO.mapOptional("Name", Fill.Name, StringRef());
1466 IO.mapOptional("Pattern", Fill.Pattern);
1467 IO.mapOptional("Offset", Fill.Offset);
1468 IO.mapRequired("Size", Fill.Size);
1469}
1470
1471static void sectionHeaderTableMapping(IO &IO,
1472 ELFYAML::SectionHeaderTable &SHT) {
1473 IO.mapOptional("Offset", SHT.Offset);
1474 IO.mapOptional("Sections", SHT.Sections);
1475 IO.mapOptional("Excluded", SHT.Excluded);
1476 IO.mapOptional("NoHeaders", SHT.NoHeaders);
1477}
1478
1479static void sectionMapping(IO &IO, ELFYAML::LinkerOptionsSection &Section) {
1480 commonSectionMapping(IO, Section);
1481 IO.mapOptional("Options", Section.Options);
1482}
1483
1484static void sectionMapping(IO &IO,
1485 ELFYAML::DependentLibrariesSection &Section) {
1486 commonSectionMapping(IO, Section);
1487 IO.mapOptional("Libraries", Section.Libs);
1488}
1489
1490static void sectionMapping(IO &IO, ELFYAML::CallGraphProfileSection &Section) {
1491 commonSectionMapping(IO, Section);
1492 IO.mapOptional("Entries", Section.Entries);
1493}
1494
1495void MappingTraits<ELFYAML::SectionOrType>::mapping(
1496 IO &IO, ELFYAML::SectionOrType &sectionOrType) {
1497 IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
1498}
1499
1500static void sectionMapping(IO &IO, ELFYAML::ARMIndexTableSection &Section) {
1501 commonSectionMapping(IO, Section);
1502 IO.mapOptional("Entries", Section.Entries);
1503}
1504
1505static void sectionMapping(IO &IO, ELFYAML::MipsABIFlags &Section) {
1506 commonSectionMapping(IO, Section);
1507 IO.mapOptional("Version", Section.Version, Hex16(0));
1508 IO.mapRequired("ISA", Section.ISALevel);
1509 IO.mapOptional("ISARevision", Section.ISARevision, Hex8(0));
1510 IO.mapOptional("ISAExtension", Section.ISAExtension,
1511 ELFYAML::MIPS_AFL_EXT(Mips::AFL_EXT_NONE));
1512 IO.mapOptional("ASEs", Section.ASEs, ELFYAML::MIPS_AFL_ASE(0));
1513 IO.mapOptional("FpABI", Section.FpABI,
1514 ELFYAML::MIPS_ABI_FP(Mips::Val_GNU_MIPS_ABI_FP_ANY));
1515 IO.mapOptional("GPRSize", Section.GPRSize,
1516 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1517 IO.mapOptional("CPR1Size", Section.CPR1Size,
1518 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1519 IO.mapOptional("CPR2Size", Section.CPR2Size,
1520 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1521 IO.mapOptional("Flags1", Section.Flags1, ELFYAML::MIPS_AFL_FLAGS1(0));
1522 IO.mapOptional("Flags2", Section.Flags2, Hex32(0));
1523}
1524
1525static StringRef getStringValue(IO &IO, const char *Key) {
1526 StringRef Val;
1527 IO.mapRequired(Key, Val);
1528 return Val;
1529}
1530
1531static void setStringValue(IO &IO, const char *Key, StringRef Val) {
1532 IO.mapRequired(Key, Val);
1533}
1534
1535static bool isInteger(StringRef Val) {
1536 APInt Tmp;
1537 return !Val.getAsInteger(0, Tmp);
1538}
1539
1540void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping(
1541 IO &IO, std::unique_ptr<ELFYAML::Chunk> &Section) {
1542 ELFYAML::ELF_SHT Type;
1
Calling defaulted default constructor for 'ELF_SHT'
3
Returning from default constructor for 'ELF_SHT'
1543 StringRef TypeStr;
1544 if (IO.outputting()) {
4
Assuming the condition is false
5
Taking false branch
1545 if (auto *S = dyn_cast<ELFYAML::Section>(Section.get()))
1546 Type = S->Type;
1547 else if (auto *SHT = dyn_cast<ELFYAML::SectionHeaderTable>(Section.get()))
1548 TypeStr = SHT->TypeStr;
1549 } else {
1550 // When the Type string does not have a "SHT_" prefix, we know it is not a
1551 // description of a regular ELF output section.
1552 TypeStr = getStringValue(IO, "Type");
1553 if (TypeStr.startswith("SHT_") || isInteger(TypeStr))
6
Assuming the condition is true
1554 IO.mapRequired("Type", Type);
7
Calling 'IO::mapRequired'
1555 }
1556
1557 if (TypeStr == "Fill") {
1558 assert(!IO.outputting())(static_cast <bool> (!IO.outputting()) ? void (0) : __assert_fail
("!IO.outputting()", "llvm/lib/ObjectYAML/ELFYAML.cpp", 1558
, __extension__ __PRETTY_FUNCTION__))
; // We don't dump fills currently.
1559 Section.reset(new ELFYAML::Fill());
1560 fillMapping(IO, *cast<ELFYAML::Fill>(Section.get()));
1561 return;
1562 }
1563
1564 if (TypeStr == ELFYAML::SectionHeaderTable::TypeStr) {
1565 if (IO.outputting())
1566 setStringValue(IO, "Type", TypeStr);
1567 else
1568 Section.reset(new ELFYAML::SectionHeaderTable(/*IsImplicit=*/false));
1569
1570 sectionHeaderTableMapping(
1571 IO, *cast<ELFYAML::SectionHeaderTable>(Section.get()));
1572 return;
1573 }
1574
1575 const auto &Obj = *static_cast<ELFYAML::Object *>(IO.getContext());
1576 if (Obj.getMachine() == ELF::EM_MIPS && Type == ELF::SHT_MIPS_ABIFLAGS) {
1577 if (!IO.outputting())
1578 Section.reset(new ELFYAML::MipsABIFlags());
1579 sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
1580 return;
1581 }
1582
1583 if (Obj.getMachine() == ELF::EM_ARM && Type == ELF::SHT_ARM_EXIDX) {
1584 if (!IO.outputting())
1585 Section.reset(new ELFYAML::ARMIndexTableSection());
1586 sectionMapping(IO, *cast<ELFYAML::ARMIndexTableSection>(Section.get()));
1587 return;
1588 }
1589
1590 switch (Type) {
1591 case ELF::SHT_DYNAMIC:
1592 if (!IO.outputting())
1593 Section.reset(new ELFYAML::DynamicSection());
1594 sectionMapping(IO, *cast<ELFYAML::DynamicSection>(Section.get()));
1595 break;
1596 case ELF::SHT_REL:
1597 case ELF::SHT_RELA:
1598 if (!IO.outputting())
1599 Section.reset(new ELFYAML::RelocationSection());
1600 sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
1601 break;
1602 case ELF::SHT_RELR:
1603 if (!IO.outputting())
1604 Section.reset(new ELFYAML::RelrSection());
1605 sectionMapping(IO, *cast<ELFYAML::RelrSection>(Section.get()));
1606 break;
1607 case ELF::SHT_GROUP:
1608 if (!IO.outputting())
1609 Section.reset(new ELFYAML::GroupSection());
1610 groupSectionMapping(IO, *cast<ELFYAML::GroupSection>(Section.get()));
1611 break;
1612 case ELF::SHT_NOBITS:
1613 if (!IO.outputting())
1614 Section.reset(new ELFYAML::NoBitsSection());
1615 sectionMapping(IO, *cast<ELFYAML::NoBitsSection>(Section.get()));
1616 break;
1617 case ELF::SHT_HASH:
1618 if (!IO.outputting())
1619 Section.reset(new ELFYAML::HashSection());
1620 sectionMapping(IO, *cast<ELFYAML::HashSection>(Section.get()));
1621 break;
1622 case ELF::SHT_NOTE:
1623 if (!IO.outputting())
1624 Section.reset(new ELFYAML::NoteSection());
1625 sectionMapping(IO, *cast<ELFYAML::NoteSection>(Section.get()));
1626 break;
1627 case ELF::SHT_GNU_HASH:
1628 if (!IO.outputting())
1629 Section.reset(new ELFYAML::GnuHashSection());
1630 sectionMapping(IO, *cast<ELFYAML::GnuHashSection>(Section.get()));
1631 break;
1632 case ELF::SHT_GNU_verdef:
1633 if (!IO.outputting())
1634 Section.reset(new ELFYAML::VerdefSection());
1635 sectionMapping(IO, *cast<ELFYAML::VerdefSection>(Section.get()));
1636 break;
1637 case ELF::SHT_GNU_versym:
1638 if (!IO.outputting())
1639 Section.reset(new ELFYAML::SymverSection());
1640 sectionMapping(IO, *cast<ELFYAML::SymverSection>(Section.get()));
1641 break;
1642 case ELF::SHT_GNU_verneed:
1643 if (!IO.outputting())
1644 Section.reset(new ELFYAML::VerneedSection());
1645 sectionMapping(IO, *cast<ELFYAML::VerneedSection>(Section.get()));
1646 break;
1647 case ELF::SHT_SYMTAB_SHNDX:
1648 if (!IO.outputting())
1649 Section.reset(new ELFYAML::SymtabShndxSection());
1650 sectionMapping(IO, *cast<ELFYAML::SymtabShndxSection>(Section.get()));
1651 break;
1652 case ELF::SHT_LLVM_ADDRSIG:
1653 if (!IO.outputting())
1654 Section.reset(new ELFYAML::AddrsigSection());
1655 sectionMapping(IO, *cast<ELFYAML::AddrsigSection>(Section.get()));
1656 break;
1657 case ELF::SHT_LLVM_LINKER_OPTIONS:
1658 if (!IO.outputting())
1659 Section.reset(new ELFYAML::LinkerOptionsSection());
1660 sectionMapping(IO, *cast<ELFYAML::LinkerOptionsSection>(Section.get()));
1661 break;
1662 case ELF::SHT_LLVM_DEPENDENT_LIBRARIES:
1663 if (!IO.outputting())
1664 Section.reset(new ELFYAML::DependentLibrariesSection());
1665 sectionMapping(IO,
1666 *cast<ELFYAML::DependentLibrariesSection>(Section.get()));
1667 break;
1668 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
1669 if (!IO.outputting())
1670 Section.reset(new ELFYAML::CallGraphProfileSection());
1671 sectionMapping(IO, *cast<ELFYAML::CallGraphProfileSection>(Section.get()));
1672 break;
1673 case ELF::SHT_LLVM_BB_ADDR_MAP_V0:
1674 case ELF::SHT_LLVM_BB_ADDR_MAP:
1675 if (!IO.outputting())
1676 Section.reset(new ELFYAML::BBAddrMapSection());
1677 sectionMapping(IO, *cast<ELFYAML::BBAddrMapSection>(Section.get()));
1678 break;
1679 default:
1680 if (!IO.outputting()) {
1681 StringRef Name;
1682 IO.mapOptional("Name", Name, StringRef());
1683 Name = ELFYAML::dropUniqueSuffix(Name);
1684
1685 if (ELFYAML::StackSizesSection::nameMatches(Name))
1686 Section = std::make_unique<ELFYAML::StackSizesSection>();
1687 else
1688 Section = std::make_unique<ELFYAML::RawContentSection>();
1689 }
1690
1691 if (auto S = dyn_cast<ELFYAML::RawContentSection>(Section.get()))
1692 sectionMapping(IO, *S);
1693 else
1694 sectionMapping(IO, *cast<ELFYAML::StackSizesSection>(Section.get()));
1695 }
1696}
1697
1698std::string MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
1699 IO &io, std::unique_ptr<ELFYAML::Chunk> &C) {
1700 if (const auto *F = dyn_cast<ELFYAML::Fill>(C.get())) {
1701 if (F->Pattern && F->Pattern->binary_size() != 0 && !F->Size)
1702 return "\"Size\" can't be 0 when \"Pattern\" is not empty";
1703 return "";
1704 }
1705
1706 if (const auto *SHT = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) {
1707 if (SHT->NoHeaders && (SHT->Sections || SHT->Excluded || SHT->Offset))
1708 return "NoHeaders can't be used together with Offset/Sections/Excluded";
1709 return "";
1710 }
1711
1712 const ELFYAML::Section &Sec = *cast<ELFYAML::Section>(C.get());
1713 if (Sec.Size && Sec.Content &&
1714 (uint64_t)(*Sec.Size) < Sec.Content->binary_size())
1715 return "Section size must be greater than or equal to the content size";
1716
1717 auto BuildErrPrefix = [](ArrayRef<std::pair<StringRef, bool>> EntV) {
1718 std::string Msg;
1719 for (size_t I = 0, E = EntV.size(); I != E; ++I) {
1720 StringRef Name = EntV[I].first;
1721 if (I == 0) {
1722 Msg = "\"" + Name.str() + "\"";
1723 continue;
1724 }
1725 if (I != EntV.size() - 1)
1726 Msg += ", \"" + Name.str() + "\"";
1727 else
1728 Msg += " and \"" + Name.str() + "\"";
1729 }
1730 return Msg;
1731 };
1732
1733 std::vector<std::pair<StringRef, bool>> Entries = Sec.getEntries();
1734 const size_t NumUsedEntries = llvm::count_if(
1735 Entries, [](const std::pair<StringRef, bool> &P) { return P.second; });
1736
1737 if ((Sec.Size || Sec.Content) && NumUsedEntries > 0)
1738 return BuildErrPrefix(Entries) +
1739 " cannot be used with \"Content\" or \"Size\"";
1740
1741 if (NumUsedEntries > 0 && Entries.size() != NumUsedEntries)
1742 return BuildErrPrefix(Entries) + " must be used together";
1743
1744 if (const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(C.get())) {
1745 if (RawSection->Flags && RawSection->ShFlags)
1746 return "ShFlags and Flags cannot be used together";
1747 return "";
1748 }
1749
1750 if (const auto *NB = dyn_cast<ELFYAML::NoBitsSection>(C.get())) {
1751 if (NB->Content)
1752 return "SHT_NOBITS section cannot have \"Content\"";
1753 return "";
1754 }
1755
1756 if (const auto *MF = dyn_cast<ELFYAML::MipsABIFlags>(C.get())) {
1757 if (MF->Content)
1758 return "\"Content\" key is not implemented for SHT_MIPS_ABIFLAGS "
1759 "sections";
1760 if (MF->Size)
1761 return "\"Size\" key is not implemented for SHT_MIPS_ABIFLAGS sections";
1762 return "";
1763 }
1764
1765 return "";
1766}
1767
1768namespace {
1769
1770struct NormalizedMips64RelType {
1771 NormalizedMips64RelType(IO &)
1772 : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1773 Type2(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1774 Type3(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1775 SpecSym(ELFYAML::ELF_REL(ELF::RSS_UNDEF)) {}
1776 NormalizedMips64RelType(IO &, ELFYAML::ELF_REL Original)
1777 : Type(Original & 0xFF), Type2(Original >> 8 & 0xFF),
1778 Type3(Original >> 16 & 0xFF), SpecSym(Original >> 24 & 0xFF) {}
1779
1780 ELFYAML::ELF_REL denormalize(IO &) {
1781 ELFYAML::ELF_REL Res = Type | Type2 << 8 | Type3 << 16 | SpecSym << 24;
1782 return Res;
1783 }
1784
1785 ELFYAML::ELF_REL Type;
1786 ELFYAML::ELF_REL Type2;
1787 ELFYAML::ELF_REL Type3;
1788 ELFYAML::ELF_RSS SpecSym;
1789};
1790
1791} // end anonymous namespace
1792
1793void MappingTraits<ELFYAML::StackSizeEntry>::mapping(
1794 IO &IO, ELFYAML::StackSizeEntry &E) {
1795 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1795, __extension__ __PRETTY_FUNCTION__
))
;
1796 IO.mapOptional("Address", E.Address, Hex64(0));
1797 IO.mapRequired("Size", E.Size);
1798}
1799
1800void MappingTraits<ELFYAML::BBAddrMapEntry>::mapping(
1801 IO &IO, ELFYAML::BBAddrMapEntry &E) {
1802 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1802, __extension__ __PRETTY_FUNCTION__
))
;
1803 IO.mapRequired("Version", E.Version);
1804 IO.mapOptional("Feature", E.Feature, Hex8(0));
1805 IO.mapOptional("Address", E.Address, Hex64(0));
1806 IO.mapOptional("NumBlocks", E.NumBlocks);
1807 IO.mapOptional("BBEntries", E.BBEntries);
1808}
1809
1810void MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry>::mapping(
1811 IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E) {
1812 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1812, __extension__ __PRETTY_FUNCTION__
))
;
1813 IO.mapOptional("ID", E.ID);
1814 IO.mapRequired("AddressOffset", E.AddressOffset);
1815 IO.mapRequired("Size", E.Size);
1816 IO.mapRequired("Metadata", E.Metadata);
1817}
1818
1819void MappingTraits<ELFYAML::GnuHashHeader>::mapping(IO &IO,
1820 ELFYAML::GnuHashHeader &E) {
1821 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1821, __extension__ __PRETTY_FUNCTION__
))
;
1822 IO.mapOptional("NBuckets", E.NBuckets);
1823 IO.mapRequired("SymNdx", E.SymNdx);
1824 IO.mapOptional("MaskWords", E.MaskWords);
1825 IO.mapRequired("Shift2", E.Shift2);
1826}
1827
1828void MappingTraits<ELFYAML::DynamicEntry>::mapping(IO &IO,
1829 ELFYAML::DynamicEntry &Rel) {
1830 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1830, __extension__ __PRETTY_FUNCTION__
))
;
1831
1832 IO.mapRequired("Tag", Rel.Tag);
1833 IO.mapRequired("Value", Rel.Val);
1834}
1835
1836void MappingTraits<ELFYAML::NoteEntry>::mapping(IO &IO, ELFYAML::NoteEntry &N) {
1837 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1837, __extension__ __PRETTY_FUNCTION__
))
;
1838
1839 IO.mapOptional("Name", N.Name);
1840 IO.mapOptional("Desc", N.Desc);
1841 IO.mapRequired("Type", N.Type);
1842}
1843
1844void MappingTraits<ELFYAML::VerdefEntry>::mapping(IO &IO,
1845 ELFYAML::VerdefEntry &E) {
1846 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1846, __extension__ __PRETTY_FUNCTION__
))
;
1847
1848 IO.mapOptional("Version", E.Version);
1849 IO.mapOptional("Flags", E.Flags);
1850 IO.mapOptional("VersionNdx", E.VersionNdx);
1851 IO.mapOptional("Hash", E.Hash);
1852 IO.mapRequired("Names", E.VerNames);
1853}
1854
1855void MappingTraits<ELFYAML::VerneedEntry>::mapping(IO &IO,
1856 ELFYAML::VerneedEntry &E) {
1857 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1857, __extension__ __PRETTY_FUNCTION__
))
;
1858
1859 IO.mapRequired("Version", E.Version);
1860 IO.mapRequired("File", E.File);
1861 IO.mapRequired("Entries", E.AuxV);
1862}
1863
1864void MappingTraits<ELFYAML::VernauxEntry>::mapping(IO &IO,
1865 ELFYAML::VernauxEntry &E) {
1866 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1866, __extension__ __PRETTY_FUNCTION__
))
;
1867
1868 IO.mapRequired("Name", E.Name);
1869 IO.mapRequired("Hash", E.Hash);
1870 IO.mapRequired("Flags", E.Flags);
1871 IO.mapRequired("Other", E.Other);
1872}
1873
1874void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
1875 ELFYAML::Relocation &Rel) {
1876 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
1877 assert(Object && "The IO context is not initialized")(static_cast <bool> (Object && "The IO context is not initialized"
) ? void (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1877, __extension__ __PRETTY_FUNCTION__
))
;
1878
1879 IO.mapOptional("Offset", Rel.Offset, (Hex64)0);
1880 IO.mapOptional("Symbol", Rel.Symbol);
1881
1882 if (Object->getMachine() == ELFYAML::ELF_EM(ELF::EM_MIPS) &&
1883 Object->Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64)) {
1884 MappingNormalization<NormalizedMips64RelType, ELFYAML::ELF_REL> Key(
1885 IO, Rel.Type);
1886 IO.mapRequired("Type", Key->Type);
1887 IO.mapOptional("Type2", Key->Type2, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
1888 IO.mapOptional("Type3", Key->Type3, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
1889 IO.mapOptional("SpecSym", Key->SpecSym, ELFYAML::ELF_RSS(ELF::RSS_UNDEF));
1890 } else
1891 IO.mapRequired("Type", Rel.Type);
1892
1893 IO.mapOptional("Addend", Rel.Addend, (ELFYAML::YAMLIntUInt)0);
1894}
1895
1896void MappingTraits<ELFYAML::ARMIndexTableEntry>::mapping(
1897 IO &IO, ELFYAML::ARMIndexTableEntry &E) {
1898 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1898, __extension__ __PRETTY_FUNCTION__
))
;
1899 IO.mapRequired("Offset", E.Offset);
1900
1901 StringRef CantUnwind = "EXIDX_CANTUNWIND";
1902 if (IO.outputting() && (uint32_t)E.Value == ARM::EHABI::EXIDX_CANTUNWIND)
1903 IO.mapRequired("Value", CantUnwind);
1904 else if (!IO.outputting() && getStringValue(IO, "Value") == CantUnwind)
1905 E.Value = ARM::EHABI::EXIDX_CANTUNWIND;
1906 else
1907 IO.mapRequired("Value", E.Value);
1908}
1909
1910void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
1911 assert(!IO.getContext() && "The IO context is initialized already")(static_cast <bool> (!IO.getContext() && "The IO context is initialized already"
) ? void (0) : __assert_fail ("!IO.getContext() && \"The IO context is initialized already\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1911, __extension__ __PRETTY_FUNCTION__
))
;
1912 IO.setContext(&Object);
1913 IO.mapTag("!ELF", true);
1914 IO.mapRequired("FileHeader", Object.Header);
1915 IO.mapOptional("ProgramHeaders", Object.ProgramHeaders);
1916 IO.mapOptional("Sections", Object.Chunks);
1917 IO.mapOptional("Symbols", Object.Symbols);
1918 IO.mapOptional("DynamicSymbols", Object.DynamicSymbols);
1919 IO.mapOptional("DWARF", Object.DWARF);
1920 if (Object.DWARF) {
1921 Object.DWARF->IsLittleEndian =
1922 Object.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
1923 Object.DWARF->Is64BitAddrSize =
1924 Object.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
1925 }
1926 IO.setContext(nullptr);
1927}
1928
1929void MappingTraits<ELFYAML::LinkerOption>::mapping(IO &IO,
1930 ELFYAML::LinkerOption &Opt) {
1931 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1931, __extension__ __PRETTY_FUNCTION__
))
;
1932 IO.mapRequired("Name", Opt.Key);
1933 IO.mapRequired("Value", Opt.Value);
1934}
1935
1936void MappingTraits<ELFYAML::CallGraphEntryWeight>::mapping(
1937 IO &IO, ELFYAML::CallGraphEntryWeight &E) {
1938 assert(IO.getContext() && "The IO context is not initialized")(static_cast <bool> (IO.getContext() && "The IO context is not initialized"
) ? void (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "llvm/lib/ObjectYAML/ELFYAML.cpp", 1938, __extension__ __PRETTY_FUNCTION__
))
;
1939 IO.mapRequired("Weight", E.Weight);
1940}
1941
1942LLVM_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; }
;
1943LLVM_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; }
;
1944LLVM_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;
};
1945LLVM_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;
};
1946LLVM_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;
};
1947
1948} // end namespace yaml
1949
1950} // end namespace llvm

/build/source/llvm/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/BinaryFormat/ELF.h"
20#include "llvm/Object/ELFTypes.h"
21#include "llvm/ObjectYAML/DWARFYAML.h"
22#include "llvm/ObjectYAML/YAML.h"
23#include "llvm/Support/YAMLTraits.h"
24#include <cstdint>
25#include <memory>
26#include <optional>
27#include <vector>
28
29namespace llvm {
30namespace ELFYAML {
31
32StringRef dropUniqueSuffix(StringRef S);
33std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
34
35// These types are invariant across 32/64-bit ELF, so for simplicity just
36// directly give them their exact sizes. We don't need to worry about
37// endianness because these are just the types in the YAMLIO structures,
38// and are appropriately converted to the necessary endianness when
39// reading/generating binary object files.
40// The naming of these types is intended to be ELF_PREFIX, where PREFIX is
41// the common prefix of the respective constants. E.g. ELF_EM corresponds
42// to the `e_machine` constants, like `EM_X86_64`.
43// In the future, these would probably be better suited by C++11 enum
44// class's with appropriate fixed underlying type.
45LLVM_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
; };
46LLVM_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
; };
47LLVM_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
; };
48LLVM_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; }
;
49LLVM_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; }
;
50LLVM_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; }
;
51// Just use 64, since it can hold 32-bit values too.
52LLVM_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
; };
53// Just use 64, since it can hold 32-bit values too.
54LLVM_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; };
55LLVM_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
; };
56LLVM_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'
57LLVM_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; };
58LLVM_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; };
59// Just use 64, since it can hold 32-bit values too.
60LLVM_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; };
61LLVM_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; };
62LLVM_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; };
63LLVM_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; };
64LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_NT)struct ELF_NT { ELF_NT() = default; ELF_NT(const uint32_t v) :
value(v) {} ELF_NT(const ELF_NT &v) = default; ELF_NT &
operator=(const ELF_NT &rhs) = default; ELF_NT &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_NT &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_NT &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
65
66LLVM_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; }
;
67LLVM_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; }
;
68LLVM_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;
};
69LLVM_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;
};
70LLVM_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;
};
71LLVM_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; };
72
73LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)struct YAMLFlowString { YAMLFlowString() = default; YAMLFlowString
(const StringRef v) : value(v) {} YAMLFlowString(const YAMLFlowString
&v) = default; YAMLFlowString &operator=(const YAMLFlowString
&rhs) = default; YAMLFlowString &operator=(const StringRef
&rhs) { value = rhs; return *this; } operator const StringRef
& () const { return value; } bool operator==(const YAMLFlowString
&rhs) const { return value == rhs.value; } bool operator
==(const StringRef &rhs) const { return value == rhs; } bool
operator<(const YAMLFlowString &rhs) const { return value
< rhs.value; } StringRef value; using BaseType = StringRef
; };
74LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)struct YAMLIntUInt { YAMLIntUInt() = default; YAMLIntUInt(const
int64_t v) : value(v) {} YAMLIntUInt(const YAMLIntUInt &
v) = default; YAMLIntUInt &operator=(const YAMLIntUInt &
rhs) = default; YAMLIntUInt &operator=(const int64_t &
rhs) { value = rhs; return *this; } operator const int64_t &
() const { return value; } bool operator==(const YAMLIntUInt
&rhs) const { return value == rhs.value; } bool operator
==(const int64_t &rhs) const { return value == rhs; } bool
operator<(const YAMLIntUInt &rhs) const { return value
< rhs.value; } int64_t value; using BaseType = int64_t; }
;
75
76template <class ELFT>
77unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType,
78 StringRef SecName) {
79 if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS)
80 return sizeof(object::Elf_Mips_ABIFlags<ELFT>);
81
82 switch (SecType) {
83 case ELF::SHT_SYMTAB:
84 case ELF::SHT_DYNSYM:
85 return sizeof(typename ELFT::Sym);
86 case ELF::SHT_GROUP:
87 return sizeof(typename ELFT::Word);
88 case ELF::SHT_REL:
89 return sizeof(typename ELFT::Rel);
90 case ELF::SHT_RELA:
91 return sizeof(typename ELFT::Rela);
92 case ELF::SHT_RELR:
93 return sizeof(typename ELFT::Relr);
94 case ELF::SHT_DYNAMIC:
95 return sizeof(typename ELFT::Dyn);
96 case ELF::SHT_HASH:
97 return sizeof(typename ELFT::Word);
98 case ELF::SHT_SYMTAB_SHNDX:
99 return sizeof(typename ELFT::Word);
100 case ELF::SHT_GNU_versym:
101 return sizeof(typename ELFT::Half);
102 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
103 return sizeof(object::Elf_CGProfile_Impl<ELFT>);
104 default:
105 if (SecName == ".debug_str")
106 return 1;
107 return 0;
108 }
109}
110
111// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
112// since 64-bit can hold 32-bit values too.
113struct FileHeader {
114 ELF_ELFCLASS Class;
115 ELF_ELFDATA Data;
116 ELF_ELFOSABI OSABI;
117 llvm::yaml::Hex8 ABIVersion;
118 ELF_ET Type;
119 std::optional<ELF_EM> Machine;
120 ELF_EF Flags;
121 llvm::yaml::Hex64 Entry;
122 std::optional<StringRef> SectionHeaderStringTable;
123
124 std::optional<llvm::yaml::Hex64> EPhOff;
125 std::optional<llvm::yaml::Hex16> EPhEntSize;
126 std::optional<llvm::yaml::Hex16> EPhNum;
127 std::optional<llvm::yaml::Hex16> EShEntSize;
128 std::optional<llvm::yaml::Hex64> EShOff;
129 std::optional<llvm::yaml::Hex16> EShNum;
130 std::optional<llvm::yaml::Hex16> EShStrNdx;
131};
132
133struct SectionHeader {
134 StringRef Name;
135};
136
137struct Symbol {
138 StringRef Name;
139 ELF_STT Type;
140 std::optional<StringRef> Section;
141 std::optional<ELF_SHN> Index;
142 ELF_STB Binding;
143 std::optional<llvm::yaml::Hex64> Value;
144 std::optional<llvm::yaml::Hex64> Size;
145 std::optional<uint8_t> Other;
146
147 std::optional<uint32_t> StName;
148};
149
150struct SectionOrType {
151 StringRef sectionNameOrType;
152};
153
154struct DynamicEntry {
155 ELF_DYNTAG Tag;
156 llvm::yaml::Hex64 Val;
157};
158
159struct BBAddrMapEntry {
160 struct BBEntry {
161 uint32_t ID;
162 llvm::yaml::Hex64 AddressOffset;
163 llvm::yaml::Hex64 Size;
164 llvm::yaml::Hex64 Metadata;
165 };
166 uint8_t Version;
167 llvm::yaml::Hex8 Feature;
168 llvm::yaml::Hex64 Address;
169 std::optional<uint64_t> NumBlocks;
170 std::optional<std::vector<BBEntry>> BBEntries;
171};
172
173struct StackSizeEntry {
174 llvm::yaml::Hex64 Address;
175 llvm::yaml::Hex64 Size;
176};
177
178struct NoteEntry {
179 StringRef Name;
180 yaml::BinaryRef Desc;
181 ELF_NT Type;
182};
183
184struct Chunk {
185 enum class ChunkKind {
186 Dynamic,
187 Group,
188 RawContent,
189 Relocation,
190 Relr,
191 NoBits,
192 Note,
193 Hash,
194 GnuHash,
195 Verdef,
196 Verneed,
197 StackSizes,
198 SymtabShndxSection,
199 Symver,
200 ARMIndexTable,
201 MipsABIFlags,
202 Addrsig,
203 LinkerOptions,
204 DependentLibraries,
205 CallGraphProfile,
206 BBAddrMap,
207
208 // Special chunks.
209 SpecialChunksStart,
210 Fill = SpecialChunksStart,
211 SectionHeaderTable,
212 };
213
214 ChunkKind Kind;
215 StringRef Name;
216 std::optional<llvm::yaml::Hex64> Offset;
217
218 // Usually chunks are not created implicitly, but rather loaded from YAML.
219 // This flag is used to signal whether this is the case or not.
220 bool IsImplicit;
221
222 Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
223 virtual ~Chunk();
224};
225
226struct Section : public Chunk {
227 ELF_SHT Type;
228 std::optional<ELF_SHF> Flags;
229 std::optional<llvm::yaml::Hex64> Address;
230 std::optional<StringRef> Link;
231 llvm::yaml::Hex64 AddressAlign;
232 std::optional<llvm::yaml::Hex64> EntSize;
233
234 std::optional<yaml::BinaryRef> Content;
235 std::optional<llvm::yaml::Hex64> Size;
236
237 // Holds the original section index.
238 unsigned OriginalSecNdx;
239
240 Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
241
242 static bool classof(const Chunk *S) {
243 return S->Kind < ChunkKind::SpecialChunksStart;
244 }
245
246 // Some derived sections might have their own special entries. This method
247 // returns a vector of <entry name, is used> pairs. It is used for section
248 // validation.
249 virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
250 return {};
251 };
252
253 // The following members are used to override section fields which is
254 // useful for creating invalid objects.
255
256 // This can be used to override the sh_addralign field.
257 std::optional<llvm::yaml::Hex64> ShAddrAlign;
258
259 // This can be used to override the offset stored in the sh_name field.
260 // It does not affect the name stored in the string table.
261 std::optional<llvm::yaml::Hex64> ShName;
262
263 // This can be used to override the sh_offset field. It does not place the
264 // section data at the offset specified.
265 std::optional<llvm::yaml::Hex64> ShOffset;
266
267 // This can be used to override the sh_size field. It does not affect the
268 // content written.
269 std::optional<llvm::yaml::Hex64> ShSize;
270
271 // This can be used to override the sh_flags field.
272 std::optional<llvm::yaml::Hex64> ShFlags;
273
274 // This can be used to override the sh_type field. It is useful when we
275 // want to use specific YAML keys for a section of a particular type to
276 // describe the content, but still want to have a different final type
277 // for the section.
278 std::optional<ELF_SHT> ShType;
279};
280
281// Fill is a block of data which is placed outside of sections. It is
282// not present in the sections header table, but it might affect the output file
283// size and program headers produced.
284struct Fill : Chunk {
285 std::optional<yaml::BinaryRef> Pattern;
286 llvm::yaml::Hex64 Size;
287
288 Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
289
290 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
291};
292
293struct SectionHeaderTable : Chunk {
294 SectionHeaderTable(bool IsImplicit)
295 : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
296
297 static bool classof(const Chunk *S) {
298 return S->Kind == ChunkKind::SectionHeaderTable;
299 }
300
301 std::optional<std::vector<SectionHeader>> Sections;
302 std::optional<std::vector<SectionHeader>> Excluded;
303 std::optional<bool> NoHeaders;
304
305 size_t getNumHeaders(size_t SectionsNum) const {
306 if (IsImplicit || isDefault())
307 return SectionsNum;
308 if (NoHeaders)
309 return (*NoHeaders) ? 0 : SectionsNum;
310 return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
311 }
312
313 bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
314
315 static constexpr StringRef TypeStr = "SectionHeaderTable";
316};
317
318struct BBAddrMapSection : Section {
319 std::optional<std::vector<BBAddrMapEntry>> Entries;
320
321 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
322
323 std::vector<std::pair<StringRef, bool>> getEntries() const override {
324 return {{"Entries", Entries.has_value()}};
325 };
326
327 static bool classof(const Chunk *S) {
328 return S->Kind == ChunkKind::BBAddrMap;
329 }
330};
331
332struct StackSizesSection : Section {
333 std::optional<std::vector<StackSizeEntry>> Entries;
334
335 StackSizesSection() : Section(ChunkKind::StackSizes) {}
336
337 std::vector<std::pair<StringRef, bool>> getEntries() const override {
338 return {{"Entries", Entries.has_value()}};
339 };
340
341 static bool classof(const Chunk *S) {
342 return S->Kind == ChunkKind::StackSizes;
343 }
344
345 static bool nameMatches(StringRef Name) {
346 return Name == ".stack_sizes";
347 }
348};
349
350struct DynamicSection : Section {
351 std::optional<std::vector<DynamicEntry>> Entries;
352
353 DynamicSection() : Section(ChunkKind::Dynamic) {}
354
355 std::vector<std::pair<StringRef, bool>> getEntries() const override {
356 return {{"Entries", Entries.has_value()}};
357 };
358
359 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
360};
361
362struct RawContentSection : Section {
363 std::optional<llvm::yaml::Hex64> Info;
364
365 RawContentSection() : Section(ChunkKind::RawContent) {}
366
367 static bool classof(const Chunk *S) {
368 return S->Kind == ChunkKind::RawContent;
369 }
370
371 // Is used when a content is read as an array of bytes.
372 std::optional<std::vector<uint8_t>> ContentBuf;
373};
374
375struct NoBitsSection : Section {
376 NoBitsSection() : Section(ChunkKind::NoBits) {}
377
378 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
379};
380
381struct NoteSection : Section {
382 std::optional<std::vector<ELFYAML::NoteEntry>> Notes;
383
384 NoteSection() : Section(ChunkKind::Note) {}
385
386 std::vector<std::pair<StringRef, bool>> getEntries() const override {
387 return {{"Notes", Notes.has_value()}};
388 };
389
390 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
391};
392
393struct HashSection : Section {
394 std::optional<std::vector<uint32_t>> Bucket;
395 std::optional<std::vector<uint32_t>> Chain;
396
397 std::vector<std::pair<StringRef, bool>> getEntries() const override {
398 return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}};
399 };
400
401 // The following members are used to override section fields.
402 // This is useful for creating invalid objects.
403 std::optional<llvm::yaml::Hex64> NBucket;
404 std::optional<llvm::yaml::Hex64> NChain;
405
406 HashSection() : Section(ChunkKind::Hash) {}
407
408 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
409};
410
411struct GnuHashHeader {
412 // The number of hash buckets.
413 // Not used when dumping the object, but can be used to override
414 // the real number of buckets when emiting an object from a YAML document.
415 std::optional<llvm::yaml::Hex32> NBuckets;
416
417 // Index of the first symbol in the dynamic symbol table
418 // included in the hash table.
419 llvm::yaml::Hex32 SymNdx;
420
421 // The number of words in the Bloom filter.
422 // Not used when dumping the object, but can be used to override the real
423 // number of words in the Bloom filter when emiting an object from a YAML
424 // document.
425 std::optional<llvm::yaml::Hex32> MaskWords;
426
427 // A shift constant used by the Bloom filter.
428 llvm::yaml::Hex32 Shift2;
429};
430
431struct GnuHashSection : Section {
432 std::optional<GnuHashHeader> Header;
433 std::optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
434 std::optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
435 std::optional<std::vector<llvm::yaml::Hex32>> HashValues;
436
437 GnuHashSection() : Section(ChunkKind::GnuHash) {}
438
439 std::vector<std::pair<StringRef, bool>> getEntries() const override {
440 return {{"Header", Header.has_value()},
441 {"BloomFilter", BloomFilter.has_value()},
442 {"HashBuckets", HashBuckets.has_value()},
443 {"HashValues", HashValues.has_value()}};
444 };
445
446 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
447};
448
449struct VernauxEntry {
450 uint32_t Hash;
451 uint16_t Flags;
452 uint16_t Other;
453 StringRef Name;
454};
455
456struct VerneedEntry {
457 uint16_t Version;
458 StringRef File;
459 std::vector<VernauxEntry> AuxV;
460};
461
462struct VerneedSection : Section {
463 std::optional<std::vector<VerneedEntry>> VerneedV;
464 std::optional<llvm::yaml::Hex64> Info;
465
466 VerneedSection() : Section(ChunkKind::Verneed) {}
467
468 std::vector<std::pair<StringRef, bool>> getEntries() const override {
469 return {{"Dependencies", VerneedV.has_value()}};
470 };
471
472 static bool classof(const Chunk *S) {
473 return S->Kind == ChunkKind::Verneed;
474 }
475};
476
477struct AddrsigSection : Section {
478 std::optional<std::vector<YAMLFlowString>> Symbols;
479
480 AddrsigSection() : Section(ChunkKind::Addrsig) {}
481
482 std::vector<std::pair<StringRef, bool>> getEntries() const override {
483 return {{"Symbols", Symbols.has_value()}};
484 };
485
486 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
487};
488
489struct LinkerOption {
490 StringRef Key;
491 StringRef Value;
492};
493
494struct LinkerOptionsSection : Section {
495 std::optional<std::vector<LinkerOption>> Options;
496
497 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
498
499 std::vector<std::pair<StringRef, bool>> getEntries() const override {
500 return {{"Options", Options.has_value()}};
501 };
502
503 static bool classof(const Chunk *S) {
504 return S->Kind == ChunkKind::LinkerOptions;
505 }
506};
507
508struct DependentLibrariesSection : Section {
509 std::optional<std::vector<YAMLFlowString>> Libs;
510
511 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
512
513 std::vector<std::pair<StringRef, bool>> getEntries() const override {
514 return {{"Libraries", Libs.has_value()}};
515 };
516
517 static bool classof(const Chunk *S) {
518 return S->Kind == ChunkKind::DependentLibraries;
519 }
520};
521
522// Represents the call graph profile section entry.
523struct CallGraphEntryWeight {
524 // The weight of the edge.
525 uint64_t Weight;
526};
527
528struct CallGraphProfileSection : Section {
529 std::optional<std::vector<CallGraphEntryWeight>> Entries;
530
531 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
532
533 std::vector<std::pair<StringRef, bool>> getEntries() const override {
534 return {{"Entries", Entries.has_value()}};
535 };
536
537 static bool classof(const Chunk *S) {
538 return S->Kind == ChunkKind::CallGraphProfile;
539 }
540};
541
542struct SymverSection : Section {
543 std::optional<std::vector<uint16_t>> Entries;
544
545 SymverSection() : Section(ChunkKind::Symver) {}
546
547 std::vector<std::pair<StringRef, bool>> getEntries() const override {
548 return {{"Entries", Entries.has_value()}};
549 };
550
551 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
552};
553
554struct VerdefEntry {
555 std::optional<uint16_t> Version;
556 std::optional<uint16_t> Flags;
557 std::optional<uint16_t> VersionNdx;
558 std::optional<uint32_t> Hash;
559 std::vector<StringRef> VerNames;
560};
561
562struct VerdefSection : Section {
563 std::optional<std::vector<VerdefEntry>> Entries;
564 std::optional<llvm::yaml::Hex64> Info;
565
566 VerdefSection() : Section(ChunkKind::Verdef) {}
567
568 std::vector<std::pair<StringRef, bool>> getEntries() const override {
569 return {{"Entries", Entries.has_value()}};
570 };
571
572 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
573};
574
575struct GroupSection : Section {
576 // Members of a group contain a flag and a list of section indices
577 // that are part of the group.
578 std::optional<std::vector<SectionOrType>> Members;
579 std::optional<StringRef> Signature; /* Info */
580
581 GroupSection() : Section(ChunkKind::Group) {}
582
583 std::vector<std::pair<StringRef, bool>> getEntries() const override {
584 return {{"Members", Members.has_value()}};
585 };
586
587 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
588};
589
590struct Relocation {
591 llvm::yaml::Hex64 Offset;
592 YAMLIntUInt Addend;
593 ELF_REL Type;
594 std::optional<StringRef> Symbol;
595};
596
597struct RelocationSection : Section {
598 std::optional<std::vector<Relocation>> Relocations;
599 StringRef RelocatableSec; /* Info */
600
601 RelocationSection() : Section(ChunkKind::Relocation) {}
602
603 std::vector<std::pair<StringRef, bool>> getEntries() const override {
604 return {{"Relocations", Relocations.has_value()}};
605 };
606
607 static bool classof(const Chunk *S) {
608 return S->Kind == ChunkKind::Relocation;
609 }
610};
611
612struct RelrSection : Section {
613 std::optional<std::vector<llvm::yaml::Hex64>> Entries;
614
615 RelrSection() : Section(ChunkKind::Relr) {}
616
617 std::vector<std::pair<StringRef, bool>> getEntries() const override {
618 return {{"Entries", Entries.has_value()}};
619 };
620
621 static bool classof(const Chunk *S) {
622 return S->Kind == ChunkKind::Relr;
623 }
624};
625
626struct SymtabShndxSection : Section {
627 std::optional<std::vector<uint32_t>> Entries;
628
629 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
630
631 std::vector<std::pair<StringRef, bool>> getEntries() const override {
632 return {{"Entries", Entries.has_value()}};
633 };
634
635 static bool classof(const Chunk *S) {
636 return S->Kind == ChunkKind::SymtabShndxSection;
637 }
638};
639
640struct ARMIndexTableEntry {
641 llvm::yaml::Hex32 Offset;
642 llvm::yaml::Hex32 Value;
643};
644
645struct ARMIndexTableSection : Section {
646 std::optional<std::vector<ARMIndexTableEntry>> Entries;
647
648 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
649
650 std::vector<std::pair<StringRef, bool>> getEntries() const override {
651 return {{"Entries", Entries.has_value()}};
652 };
653
654 static bool classof(const Chunk *S) {
655 return S->Kind == ChunkKind::ARMIndexTable;
656 }
657};
658
659// Represents .MIPS.abiflags section
660struct MipsABIFlags : Section {
661 llvm::yaml::Hex16 Version;
662 MIPS_ISA ISALevel;
663 llvm::yaml::Hex8 ISARevision;
664 MIPS_AFL_REG GPRSize;
665 MIPS_AFL_REG CPR1Size;
666 MIPS_AFL_REG CPR2Size;
667 MIPS_ABI_FP FpABI;
668 MIPS_AFL_EXT ISAExtension;
669 MIPS_AFL_ASE ASEs;
670 MIPS_AFL_FLAGS1 Flags1;
671 llvm::yaml::Hex32 Flags2;
672
673 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
674
675 static bool classof(const Chunk *S) {
676 return S->Kind == ChunkKind::MipsABIFlags;
677 }
678};
679
680struct ProgramHeader {
681 ELF_PT Type;
682 ELF_PF Flags;
683 llvm::yaml::Hex64 VAddr;
684 llvm::yaml::Hex64 PAddr;
685 std::optional<llvm::yaml::Hex64> Align;
686 std::optional<llvm::yaml::Hex64> FileSize;
687 std::optional<llvm::yaml::Hex64> MemSize;
688 std::optional<llvm::yaml::Hex64> Offset;
689 std::optional<StringRef> FirstSec;
690 std::optional<StringRef> LastSec;
691
692 // This vector contains all chunks from [FirstSec, LastSec].
693 std::vector<Chunk *> Chunks;
694};
695
696struct Object {
697 FileHeader Header;
698 std::vector<ProgramHeader> ProgramHeaders;
699
700 // An object might contain output section descriptions as well as
701 // custom data that does not belong to any section.
702 std::vector<std::unique_ptr<Chunk>> Chunks;
703
704 // Although in reality the symbols reside in a section, it is a lot
705 // cleaner and nicer if we read them from the YAML as a separate
706 // top-level key, which automatically ensures that invariants like there
707 // being a single SHT_SYMTAB section are upheld.
708 std::optional<std::vector<Symbol>> Symbols;
709 std::optional<std::vector<Symbol>> DynamicSymbols;
710 std::optional<DWARFYAML::Data> DWARF;
711
712 std::vector<Section *> getSections() {
713 std::vector<Section *> Ret;
714 for (const std::unique_ptr<Chunk> &Sec : Chunks)
715 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
716 Ret.push_back(S);
717 return Ret;
718 }
719
720 const SectionHeaderTable &getSectionHeaderTable() const {
721 for (const std::unique_ptr<Chunk> &C : Chunks)
722 if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
723 return *S;
724 llvm_unreachable("the section header table chunk must always be present")::llvm::llvm_unreachable_internal("the section header table chunk must always be present"
, "llvm/include/llvm/ObjectYAML/ELFYAML.h", 724)
;
725 }
726
727 ELF_ELFOSABI getOSAbi() const;
728 unsigned getMachine() const;
729};
730
731bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
732 const NoBitsSection &S);
733
734} // end namespace ELFYAML
735} // end namespace llvm
736
737LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::StackSizeEntry> && !std::is_same_v
<llvm::ELFYAML::StackSizeEntry, std::string> &&
!std::is_same_v<llvm::ELFYAML::StackSizeEntry, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::StackSizeEntry> { static const bool flow = false; }; } }
738LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::BBAddrMapEntry> && !std::is_same_v
<llvm::ELFYAML::BBAddrMapEntry, std::string> &&
!std::is_same_v<llvm::ELFYAML::BBAddrMapEntry, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::BBAddrMapEntry> { static const bool flow = false; }; } }
739LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::BBAddrMapEntry::BBEntry> && !std
::is_same_v<llvm::ELFYAML::BBAddrMapEntry::BBEntry, std::string
> && !std::is_same_v<llvm::ELFYAML::BBAddrMapEntry
::BBEntry, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::BBAddrMapEntry::BBEntry> { static const bool flow = false
; }; } }
740LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::DynamicEntry> && !std::is_same_v
<llvm::ELFYAML::DynamicEntry, std::string> && !
std::is_same_v<llvm::ELFYAML::DynamicEntry, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::DynamicEntry> { static const bool flow = false; }; } }
741LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::LinkerOption> && !std::is_same_v
<llvm::ELFYAML::LinkerOption, std::string> && !
std::is_same_v<llvm::ELFYAML::LinkerOption, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::LinkerOption> { static const bool flow = false; }; } }
742LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::CallGraphEntryWeight> && !std::
is_same_v<llvm::ELFYAML::CallGraphEntryWeight, std::string
> && !std::is_same_v<llvm::ELFYAML::CallGraphEntryWeight
, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::CallGraphEntryWeight> { static const bool flow = false; }
; } }
743LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::NoteEntry> && !std::is_same_v<
llvm::ELFYAML::NoteEntry, std::string> && !std::is_same_v
<llvm::ELFYAML::NoteEntry, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::NoteEntry> { static const bool flow = false; }; } }
744LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::ProgramHeader> && !std::is_same_v
<llvm::ELFYAML::ProgramHeader, std::string> && !
std::is_same_v<llvm::ELFYAML::ProgramHeader, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::ProgramHeader> { static const bool flow = false; }; } }
745LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::SectionHeader> && !std::is_same_v
<llvm::ELFYAML::SectionHeader, std::string> && !
std::is_same_v<llvm::ELFYAML::SectionHeader, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::SectionHeader> { static const bool flow = false; }; } }
746LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<std::unique_ptr<llvm::ELFYAML::Chunk> > &&
!std::is_same_v<std::unique_ptr<llvm::ELFYAML::Chunk>
, std::string> && !std::is_same_v<std::unique_ptr
<llvm::ELFYAML::Chunk>, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<std::unique_ptr
<llvm::ELFYAML::Chunk> > { static const bool flow = false
; }; } }
747LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::Symbol> && !std::is_same_v<llvm
::ELFYAML::Symbol, std::string> && !std::is_same_v
<llvm::ELFYAML::Symbol, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::Symbol> { static const bool flow = false; }; } }
748LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::VerdefEntry> && !std::is_same_v
<llvm::ELFYAML::VerdefEntry, std::string> && !std
::is_same_v<llvm::ELFYAML::VerdefEntry, llvm::StringRef>
, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VerdefEntry> { static const bool flow = false; }; } }
749LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::VernauxEntry> && !std::is_same_v
<llvm::ELFYAML::VernauxEntry, std::string> && !
std::is_same_v<llvm::ELFYAML::VernauxEntry, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VernauxEntry> { static const bool flow = false; }; } }
750LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::VerneedEntry> && !std::is_same_v
<llvm::ELFYAML::VerneedEntry, std::string> && !
std::is_same_v<llvm::ELFYAML::VerneedEntry, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VerneedEntry> { static const bool flow = false; }; } }
751LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::Relocation> && !std::is_same_v<
llvm::ELFYAML::Relocation, std::string> && !std::is_same_v
<llvm::ELFYAML::Relocation, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::Relocation> { static const bool flow = false; }; } }
752LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::SectionOrType> && !std::is_same_v
<llvm::ELFYAML::SectionOrType, std::string> && !
std::is_same_v<llvm::ELFYAML::SectionOrType, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::SectionOrType> { static const bool flow = false; }; } }
753LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::ARMIndexTableEntry> && !std::is_same_v
<llvm::ELFYAML::ARMIndexTableEntry, std::string> &&
!std::is_same_v<llvm::ELFYAML::ARMIndexTableEntry, llvm::
StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::ARMIndexTableEntry> { static const bool flow = false; };
} }
754
755namespace llvm {
756namespace yaml {
757
758template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
759 static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
760 raw_ostream &Out);
761 static StringRef input(StringRef Scalar, void *Ctx,
762 ELFYAML::YAMLIntUInt &Val);
763 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
764};
765
766template <>
767struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
768 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
769};
770
771template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
772 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
773};
774
775template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
776 static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
777};
778
779template <>
780struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
781 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
782};
783
784template <>
785struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
786 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
787};
788
789template <>
790struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
791 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
792};
793
794template <>
795struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
796 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
797};
798
799template <>
800struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
801 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
802};
803
804template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
805 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
806};
807
808template <>
809struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
810 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
811};
812
813template <>
814struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
815 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
816};
817
818template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
819 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
820};
821
822template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
823 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
824};
825
826template <>
827struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
828 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
829};
830
831template <>
832struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
833 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
834};
835
836template <>
837struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
838 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
839};
840
841template <>
842struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
843 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
844};
845
846template <>
847struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
848 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
849};
850
851template <>
852struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
853 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
854};
855
856template <>
857struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
858 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
859};
860
861template <>
862struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
863 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
864};
865
866template <>
867struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
868 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
869};
870
871template <>
872struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
873 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
874};
875
876template <>
877struct MappingTraits<ELFYAML::FileHeader> {
878 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
879};
880
881template <> struct MappingTraits<ELFYAML::SectionHeader> {
882 static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
883};
884
885template <> struct MappingTraits<ELFYAML::ProgramHeader> {
886 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
887 static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
888};
889
890template <>
891struct MappingTraits<ELFYAML::Symbol> {
892 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
893 static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
894};
895
896template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
897 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
898};
899
900template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
901 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
902};
903
904template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
905 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
906};
907
908template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
909 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
910};
911
912template <> struct MappingTraits<ELFYAML::DynamicEntry> {
913 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
914};
915
916template <> struct MappingTraits<ELFYAML::NoteEntry> {
917 static void mapping(IO &IO, ELFYAML::NoteEntry &N);
918};
919
920template <> struct MappingTraits<ELFYAML::VerdefEntry> {
921 static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
922};
923
924template <> struct MappingTraits<ELFYAML::VerneedEntry> {
925 static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
926};
927
928template <> struct MappingTraits<ELFYAML::VernauxEntry> {
929 static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
930};
931
932template <> struct MappingTraits<ELFYAML::LinkerOption> {
933 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
934};
935
936template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
937 static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
938};
939
940template <> struct MappingTraits<ELFYAML::Relocation> {
941 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
942};
943
944template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
945 static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
946};
947
948template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
949 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
950 static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
951};
952
953template <>
954struct MappingTraits<ELFYAML::Object> {
955 static void mapping(IO &IO, ELFYAML::Object &Object);
956};
957
958template <> struct MappingTraits<ELFYAML::SectionOrType> {
959 static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
960};
961
962} // end namespace yaml
963} // end namespace llvm
964
965#endif // LLVM_OBJECTYAML_ELFYAML_H

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