Bug Summary

File:build/source/llvm/include/llvm/ObjectYAML/ELFYAML.h
Warning:line 56, column 1
The left operand of '==' is a garbage 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-16/lib/clang/16 -I lib/ObjectYAML -I /build/source/llvm/lib/ObjectYAML -I include -I /build/source/llvm/include -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -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-16/lib/clang/16/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 1674602410 -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-01-25-024556-16494-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_FILE);
135 ECase(NT_PRXFPREG);
136 ECase(NT_SIGINFO);
137 // LLVM-specific notes.
138 ECase(NT_LLVM_HWASAN_GLOBALS);
139 // GNU note types
140 ECase(NT_GNU_ABI_TAG);
141 ECase(NT_GNU_HWCAP);
142 ECase(NT_GNU_BUILD_ID);
143 ECase(NT_GNU_GOLD_VERSION);
144 ECase(NT_GNU_PROPERTY_TYPE_0);
145 // FreeBSD note types.
146 ECase(NT_FREEBSD_ABI_TAG);
147 ECase(NT_FREEBSD_NOINIT_TAG);
148 ECase(NT_FREEBSD_ARCH_TAG);
149 ECase(NT_FREEBSD_FEATURE_CTL);
150 // FreeBSD core note types.
151 ECase(NT_FREEBSD_THRMISC);
152 ECase(NT_FREEBSD_PROCSTAT_PROC);
153 ECase(NT_FREEBSD_PROCSTAT_FILES);
154 ECase(NT_FREEBSD_PROCSTAT_VMMAP);
155 ECase(NT_FREEBSD_PROCSTAT_GROUPS);
156 ECase(NT_FREEBSD_PROCSTAT_UMASK);
157 ECase(NT_FREEBSD_PROCSTAT_RLIMIT);
158 ECase(NT_FREEBSD_PROCSTAT_OSREL);
159 ECase(NT_FREEBSD_PROCSTAT_PSSTRINGS);
160 ECase(NT_FREEBSD_PROCSTAT_AUXV);
161 // NetBSD core note types.
162 ECase(NT_NETBSDCORE_PROCINFO);
163 ECase(NT_NETBSDCORE_AUXV);
164 ECase(NT_NETBSDCORE_LWPSTATUS);
165 // OpenBSD core note types.
166 ECase(NT_OPENBSD_PROCINFO);
167 ECase(NT_OPENBSD_AUXV);
168 ECase(NT_OPENBSD_REGS);
169 ECase(NT_OPENBSD_FPREGS);
170 ECase(NT_OPENBSD_XFPREGS);
171 ECase(NT_OPENBSD_WCOOKIE);
172 // AMD specific notes. (Code Object V2)
173 ECase(NT_AMD_HSA_CODE_OBJECT_VERSION);
174 ECase(NT_AMD_HSA_HSAIL);
175 ECase(NT_AMD_HSA_ISA_VERSION);
176 ECase(NT_AMD_HSA_METADATA);
177 ECase(NT_AMD_HSA_ISA_NAME);
178 ECase(NT_AMD_PAL_METADATA);
179 // AMDGPU specific notes. (Code Object V3)
180 ECase(NT_AMDGPU_METADATA);
181 // Android specific notes.
182 ECase(NT_ANDROID_TYPE_IDENT);
183 ECase(NT_ANDROID_TYPE_KUSER);
184 ECase(NT_ANDROID_TYPE_MEMTAG);
185#undef ECase
186 IO.enumFallback<Hex32>(Value);
187}
188
189void ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(
190 IO &IO, ELFYAML::ELF_EM &Value) {
191#define ECase(X) IO.enumCase(Value, #X, ELF::X)
192 ECase(EM_NONE);
193 ECase(EM_M32);
194 ECase(EM_SPARC);
195 ECase(EM_386);
196 ECase(EM_68K);
197 ECase(EM_88K);
198 ECase(EM_IAMCU);
199 ECase(EM_860);
200 ECase(EM_MIPS);
201 ECase(EM_S370);
202 ECase(EM_MIPS_RS3_LE);
203 ECase(EM_PARISC);
204 ECase(EM_VPP500);
205 ECase(EM_SPARC32PLUS);
206 ECase(EM_960);
207 ECase(EM_PPC);
208 ECase(EM_PPC64);
209 ECase(EM_S390);
210 ECase(EM_SPU);
211 ECase(EM_V800);
212 ECase(EM_FR20);
213 ECase(EM_RH32);
214 ECase(EM_RCE);
215 ECase(EM_ARM);
216 ECase(EM_ALPHA);
217 ECase(EM_SH);
218 ECase(EM_SPARCV9);
219 ECase(EM_TRICORE);
220 ECase(EM_ARC);
221 ECase(EM_H8_300);
222 ECase(EM_H8_300H);
223 ECase(EM_H8S);
224 ECase(EM_H8_500);
225 ECase(EM_IA_64);
226 ECase(EM_MIPS_X);
227 ECase(EM_COLDFIRE);
228 ECase(EM_68HC12);
229 ECase(EM_MMA);
230 ECase(EM_PCP);
231 ECase(EM_NCPU);
232 ECase(EM_NDR1);
233 ECase(EM_STARCORE);
234 ECase(EM_ME16);
235 ECase(EM_ST100);
236 ECase(EM_TINYJ);
237 ECase(EM_X86_64);
238 ECase(EM_PDSP);
239 ECase(EM_PDP10);
240 ECase(EM_PDP11);
241 ECase(EM_FX66);
242 ECase(EM_ST9PLUS);
243 ECase(EM_ST7);
244 ECase(EM_68HC16);
245 ECase(EM_68HC11);
246 ECase(EM_68HC08);
247 ECase(EM_68HC05);
248 ECase(EM_SVX);
249 ECase(EM_ST19);
250 ECase(EM_VAX);
251 ECase(EM_CRIS);
252 ECase(EM_JAVELIN);
253 ECase(EM_FIREPATH);
254 ECase(EM_ZSP);
255 ECase(EM_MMIX);
256 ECase(EM_HUANY);
257 ECase(EM_PRISM);
258 ECase(EM_AVR);
259 ECase(EM_FR30);
260 ECase(EM_D10V);
261 ECase(EM_D30V);
262 ECase(EM_V850);
263 ECase(EM_M32R);
264 ECase(EM_MN10300);
265 ECase(EM_MN10200);
266 ECase(EM_PJ);
267 ECase(EM_OPENRISC);
268 ECase(EM_ARC_COMPACT);
269 ECase(EM_XTENSA);
270 ECase(EM_VIDEOCORE);
271 ECase(EM_TMM_GPP);
272 ECase(EM_NS32K);
273 ECase(EM_TPC);
274 ECase(EM_SNP1K);
275 ECase(EM_ST200);
276 ECase(EM_IP2K);
277 ECase(EM_MAX);
278 ECase(EM_CR);
279 ECase(EM_F2MC16);
280 ECase(EM_MSP430);
281 ECase(EM_BLACKFIN);
282 ECase(EM_SE_C33);
283 ECase(EM_SEP);
284 ECase(EM_ARCA);
285 ECase(EM_UNICORE);
286 ECase(EM_EXCESS);
287 ECase(EM_DXP);
288 ECase(EM_ALTERA_NIOS2);
289 ECase(EM_CRX);
290 ECase(EM_XGATE);
291 ECase(EM_C166);
292 ECase(EM_M16C);
293 ECase(EM_DSPIC30F);
294 ECase(EM_CE);
295 ECase(EM_M32C);
296 ECase(EM_TSK3000);
297 ECase(EM_RS08);
298 ECase(EM_SHARC);
299 ECase(EM_ECOG2);
300 ECase(EM_SCORE7);
301 ECase(EM_DSP24);
302 ECase(EM_VIDEOCORE3);
303 ECase(EM_LATTICEMICO32);
304 ECase(EM_SE_C17);
305 ECase(EM_TI_C6000);
306 ECase(EM_TI_C2000);
307 ECase(EM_TI_C5500);
308 ECase(EM_MMDSP_PLUS);
309 ECase(EM_CYPRESS_M8C);
310 ECase(EM_R32C);
311 ECase(EM_TRIMEDIA);
312 ECase(EM_HEXAGON);
313 ECase(EM_8051);
314 ECase(EM_STXP7X);
315 ECase(EM_NDS32);
316 ECase(EM_ECOG1);
317 ECase(EM_ECOG1X);
318 ECase(EM_MAXQ30);
319 ECase(EM_XIMO16);
320 ECase(EM_MANIK);
321 ECase(EM_CRAYNV2);
322 ECase(EM_RX);
323 ECase(EM_METAG);
324 ECase(EM_MCST_ELBRUS);
325 ECase(EM_ECOG16);
326 ECase(EM_CR16);
327 ECase(EM_ETPU);
328 ECase(EM_SLE9X);
329 ECase(EM_L10M);
330 ECase(EM_K10M);
331 ECase(EM_AARCH64);
332 ECase(EM_AVR32);
333 ECase(EM_STM8);
334 ECase(EM_TILE64);
335 ECase(EM_TILEPRO);
336 ECase(EM_MICROBLAZE);
337 ECase(EM_CUDA);
338 ECase(EM_TILEGX);
339 ECase(EM_CLOUDSHIELD);
340 ECase(EM_COREA_1ST);
341 ECase(EM_COREA_2ND);
342 ECase(EM_ARC_COMPACT2);
343 ECase(EM_OPEN8);
344 ECase(EM_RL78);
345 ECase(EM_VIDEOCORE5);
346 ECase(EM_78KOR);
347 ECase(EM_56800EX);
348 ECase(EM_AMDGPU);
349 ECase(EM_RISCV);
350 ECase(EM_LANAI);
351 ECase(EM_BPF);
352 ECase(EM_VE);
353 ECase(EM_CSKY);
354 ECase(EM_LOONGARCH);
355#undef ECase
356 IO.enumFallback<Hex16>(Value);
357}
358
359void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration(
360 IO &IO, ELFYAML::ELF_ELFCLASS &Value) {
361#define ECase(X) IO.enumCase(Value, #X, ELF::X)
362 // Since the semantics of ELFCLASSNONE is "invalid", just don't accept it
363 // here.
364 ECase(ELFCLASS32);
365 ECase(ELFCLASS64);
366#undef ECase
367}
368
369void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration(
370 IO &IO, ELFYAML::ELF_ELFDATA &Value) {
371#define ECase(X) IO.enumCase(Value, #X, ELF::X)
372 // ELFDATANONE is an invalid data encoding, but we accept it because
373 // we want to be able to produce invalid binaries for the tests.
374 ECase(ELFDATANONE);
375 ECase(ELFDATA2LSB);
376 ECase(ELFDATA2MSB);
377#undef ECase
378}
379
380void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
381 IO &IO, ELFYAML::ELF_ELFOSABI &Value) {
382#define ECase(X) IO.enumCase(Value, #X, ELF::X)
383 ECase(ELFOSABI_NONE);
384 ECase(ELFOSABI_HPUX);
385 ECase(ELFOSABI_NETBSD);
386 ECase(ELFOSABI_GNU);
387 ECase(ELFOSABI_LINUX);
388 ECase(ELFOSABI_HURD);
389 ECase(ELFOSABI_SOLARIS);
390 ECase(ELFOSABI_AIX);
391 ECase(ELFOSABI_IRIX);
392 ECase(ELFOSABI_FREEBSD);
393 ECase(ELFOSABI_TRU64);
394 ECase(ELFOSABI_MODESTO);
395 ECase(ELFOSABI_OPENBSD);
396 ECase(ELFOSABI_OPENVMS);
397 ECase(ELFOSABI_NSK);
398 ECase(ELFOSABI_AROS);
399 ECase(ELFOSABI_FENIXOS);
400 ECase(ELFOSABI_CLOUDABI);
401 ECase(ELFOSABI_AMDGPU_HSA);
402 ECase(ELFOSABI_AMDGPU_PAL);
403 ECase(ELFOSABI_AMDGPU_MESA3D);
404 ECase(ELFOSABI_ARM);
405 ECase(ELFOSABI_C6000_ELFABI);
406 ECase(ELFOSABI_C6000_LINUX);
407 ECase(ELFOSABI_STANDALONE);
408#undef ECase
409 IO.enumFallback<Hex8>(Value);
410}
411
412void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
413 ELFYAML::ELF_EF &Value) {
414 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
415 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", 415, __extension__ __PRETTY_FUNCTION__
))
;
416#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
417#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M)
418 switch (Object->getMachine()) {
419 case ELF::EM_ARM:
420 BCase(EF_ARM_SOFT_FLOAT);
421 BCase(EF_ARM_VFP_FLOAT);
422 BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK);
423 BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK);
424 BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK);
425 BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK);
426 BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK);
427 BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK);
428 BCaseMask(EF_ARM_BE8, EF_ARM_BE8);
429 break;
430 case ELF::EM_MIPS:
431 BCase(EF_MIPS_NOREORDER);
432 BCase(EF_MIPS_PIC);
433 BCase(EF_MIPS_CPIC);
434 BCase(EF_MIPS_ABI2);
435 BCase(EF_MIPS_32BITMODE);
436 BCase(EF_MIPS_FP64);
437 BCase(EF_MIPS_NAN2008);
438 BCase(EF_MIPS_MICROMIPS);
439 BCase(EF_MIPS_ARCH_ASE_M16);
440 BCase(EF_MIPS_ARCH_ASE_MDMX);
441 BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI);
442 BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI);
443 BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI);
444 BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI);
445 BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH);
446 BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH);
447 BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH);
448 BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH);
449 BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH);
450 BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH);
451 BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH);
452 BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH);
453 BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH);
454 BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH);
455 BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH);
456 BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH);
457 BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH);
458 BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH);
459 BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH);
460 BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH);
461 BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH);
462 BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH);
463 BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH);
464 BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH);
465 BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH);
466 BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH);
467 BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH);
468 BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH);
469 BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH);
470 BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH);
471 BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH);
472 BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH);
473 BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH);
474 break;
475 case ELF::EM_HEXAGON:
476 BCaseMask(EF_HEXAGON_MACH_V2, EF_HEXAGON_MACH);
477 BCaseMask(EF_HEXAGON_MACH_V3, EF_HEXAGON_MACH);
478 BCaseMask(EF_HEXAGON_MACH_V4, EF_HEXAGON_MACH);
479 BCaseMask(EF_HEXAGON_MACH_V5, EF_HEXAGON_MACH);
480 BCaseMask(EF_HEXAGON_MACH_V55, EF_HEXAGON_MACH);
481 BCaseMask(EF_HEXAGON_MACH_V60, EF_HEXAGON_MACH);
482 BCaseMask(EF_HEXAGON_MACH_V62, EF_HEXAGON_MACH);
483 BCaseMask(EF_HEXAGON_MACH_V65, EF_HEXAGON_MACH);
484 BCaseMask(EF_HEXAGON_MACH_V66, EF_HEXAGON_MACH);
485 BCaseMask(EF_HEXAGON_MACH_V67, EF_HEXAGON_MACH);
486 BCaseMask(EF_HEXAGON_MACH_V67T, EF_HEXAGON_MACH);
487 BCaseMask(EF_HEXAGON_MACH_V68, EF_HEXAGON_MACH);
488 BCaseMask(EF_HEXAGON_MACH_V69, EF_HEXAGON_MACH);
489 BCaseMask(EF_HEXAGON_MACH_V71, EF_HEXAGON_MACH);
490 BCaseMask(EF_HEXAGON_MACH_V71T, EF_HEXAGON_MACH);
491 BCaseMask(EF_HEXAGON_MACH_V73, EF_HEXAGON_MACH);
492 BCaseMask(EF_HEXAGON_ISA_V2, EF_HEXAGON_ISA);
493 BCaseMask(EF_HEXAGON_ISA_V3, EF_HEXAGON_ISA);
494 BCaseMask(EF_HEXAGON_ISA_V4, EF_HEXAGON_ISA);
495 BCaseMask(EF_HEXAGON_ISA_V5, EF_HEXAGON_ISA);
496 BCaseMask(EF_HEXAGON_ISA_V55, EF_HEXAGON_ISA);
497 BCaseMask(EF_HEXAGON_ISA_V60, EF_HEXAGON_ISA);
498 BCaseMask(EF_HEXAGON_ISA_V62, EF_HEXAGON_ISA);
499 BCaseMask(EF_HEXAGON_ISA_V65, EF_HEXAGON_ISA);
500 BCaseMask(EF_HEXAGON_ISA_V66, EF_HEXAGON_ISA);
501 BCaseMask(EF_HEXAGON_ISA_V67, EF_HEXAGON_ISA);
502 BCaseMask(EF_HEXAGON_ISA_V68, EF_HEXAGON_ISA);
503 BCaseMask(EF_HEXAGON_ISA_V69, EF_HEXAGON_ISA);
504 BCaseMask(EF_HEXAGON_ISA_V71, EF_HEXAGON_ISA);
505 BCaseMask(EF_HEXAGON_ISA_V73, EF_HEXAGON_ISA);
506 break;
507 case ELF::EM_AVR:
508 BCaseMask(EF_AVR_ARCH_AVR1, EF_AVR_ARCH_MASK);
509 BCaseMask(EF_AVR_ARCH_AVR2, EF_AVR_ARCH_MASK);
510 BCaseMask(EF_AVR_ARCH_AVR25, EF_AVR_ARCH_MASK);
511 BCaseMask(EF_AVR_ARCH_AVR3, EF_AVR_ARCH_MASK);
512 BCaseMask(EF_AVR_ARCH_AVR31, EF_AVR_ARCH_MASK);
513 BCaseMask(EF_AVR_ARCH_AVR35, EF_AVR_ARCH_MASK);
514 BCaseMask(EF_AVR_ARCH_AVR4, EF_AVR_ARCH_MASK);
515 BCaseMask(EF_AVR_ARCH_AVR5, EF_AVR_ARCH_MASK);
516 BCaseMask(EF_AVR_ARCH_AVR51, EF_AVR_ARCH_MASK);
517 BCaseMask(EF_AVR_ARCH_AVR6, EF_AVR_ARCH_MASK);
518 BCaseMask(EF_AVR_ARCH_AVRTINY, EF_AVR_ARCH_MASK);
519 BCaseMask(EF_AVR_ARCH_XMEGA1, EF_AVR_ARCH_MASK);
520 BCaseMask(EF_AVR_ARCH_XMEGA2, EF_AVR_ARCH_MASK);
521 BCaseMask(EF_AVR_ARCH_XMEGA3, EF_AVR_ARCH_MASK);
522 BCaseMask(EF_AVR_ARCH_XMEGA4, EF_AVR_ARCH_MASK);
523 BCaseMask(EF_AVR_ARCH_XMEGA5, EF_AVR_ARCH_MASK);
524 BCaseMask(EF_AVR_ARCH_XMEGA6, EF_AVR_ARCH_MASK);
525 BCaseMask(EF_AVR_ARCH_XMEGA7, EF_AVR_ARCH_MASK);
526 BCase(EF_AVR_LINKRELAX_PREPARED);
527 break;
528 case ELF::EM_LOONGARCH:
529 BCaseMask(EF_LOONGARCH_ABI_SOFT_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK);
530 BCaseMask(EF_LOONGARCH_ABI_SINGLE_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK);
531 BCaseMask(EF_LOONGARCH_ABI_DOUBLE_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK);
532 BCaseMask(EF_LOONGARCH_OBJABI_V0, EF_LOONGARCH_OBJABI_MASK);
533 BCaseMask(EF_LOONGARCH_OBJABI_V1, EF_LOONGARCH_OBJABI_MASK);
534 break;
535 case ELF::EM_RISCV:
536 BCase(EF_RISCV_RVC);
537 BCaseMask(EF_RISCV_FLOAT_ABI_SOFT, EF_RISCV_FLOAT_ABI);
538 BCaseMask(EF_RISCV_FLOAT_ABI_SINGLE, EF_RISCV_FLOAT_ABI);
539 BCaseMask(EF_RISCV_FLOAT_ABI_DOUBLE, EF_RISCV_FLOAT_ABI);
540 BCaseMask(EF_RISCV_FLOAT_ABI_QUAD, EF_RISCV_FLOAT_ABI);
541 BCase(EF_RISCV_RVE);
542 BCase(EF_RISCV_TSO);
543 break;
544 case ELF::EM_XTENSA:
545 BCase(EF_XTENSA_XT_INSN);
546 BCaseMask(EF_XTENSA_MACH_NONE, EF_XTENSA_MACH);
547 BCase(EF_XTENSA_XT_LIT);
548 break;
549 case ELF::EM_AMDGPU:
550 BCaseMask(EF_AMDGPU_MACH_NONE, EF_AMDGPU_MACH);
551 BCaseMask(EF_AMDGPU_MACH_R600_R600, EF_AMDGPU_MACH);
552 BCaseMask(EF_AMDGPU_MACH_R600_R630, EF_AMDGPU_MACH);
553 BCaseMask(EF_AMDGPU_MACH_R600_RS880, EF_AMDGPU_MACH);
554 BCaseMask(EF_AMDGPU_MACH_R600_RV670, EF_AMDGPU_MACH);
555 BCaseMask(EF_AMDGPU_MACH_R600_RV710, EF_AMDGPU_MACH);
556 BCaseMask(EF_AMDGPU_MACH_R600_RV730, EF_AMDGPU_MACH);
557 BCaseMask(EF_AMDGPU_MACH_R600_RV770, EF_AMDGPU_MACH);
558 BCaseMask(EF_AMDGPU_MACH_R600_CEDAR, EF_AMDGPU_MACH);
559 BCaseMask(EF_AMDGPU_MACH_R600_CYPRESS, EF_AMDGPU_MACH);
560 BCaseMask(EF_AMDGPU_MACH_R600_JUNIPER, EF_AMDGPU_MACH);
561 BCaseMask(EF_AMDGPU_MACH_R600_REDWOOD, EF_AMDGPU_MACH);
562 BCaseMask(EF_AMDGPU_MACH_R600_SUMO, EF_AMDGPU_MACH);
563 BCaseMask(EF_AMDGPU_MACH_R600_BARTS, EF_AMDGPU_MACH);
564 BCaseMask(EF_AMDGPU_MACH_R600_CAICOS, EF_AMDGPU_MACH);
565 BCaseMask(EF_AMDGPU_MACH_R600_CAYMAN, EF_AMDGPU_MACH);
566 BCaseMask(EF_AMDGPU_MACH_R600_TURKS, EF_AMDGPU_MACH);
567 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX600, EF_AMDGPU_MACH);
568 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX601, EF_AMDGPU_MACH);
569 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX602, EF_AMDGPU_MACH);
570 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX700, EF_AMDGPU_MACH);
571 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX701, EF_AMDGPU_MACH);
572 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX702, EF_AMDGPU_MACH);
573 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX703, EF_AMDGPU_MACH);
574 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX704, EF_AMDGPU_MACH);
575 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX705, EF_AMDGPU_MACH);
576 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX801, EF_AMDGPU_MACH);
577 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX802, EF_AMDGPU_MACH);
578 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX803, EF_AMDGPU_MACH);
579 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX805, EF_AMDGPU_MACH);
580 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX810, EF_AMDGPU_MACH);
581 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX900, EF_AMDGPU_MACH);
582 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX902, EF_AMDGPU_MACH);
583 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX904, EF_AMDGPU_MACH);
584 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX906, EF_AMDGPU_MACH);
585 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX908, EF_AMDGPU_MACH);
586 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX909, EF_AMDGPU_MACH);
587 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX90A, EF_AMDGPU_MACH);
588 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX90C, EF_AMDGPU_MACH);
589 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX940, EF_AMDGPU_MACH);
590 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1010, EF_AMDGPU_MACH);
591 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1011, EF_AMDGPU_MACH);
592 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1012, EF_AMDGPU_MACH);
593 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1013, EF_AMDGPU_MACH);
594 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1030, EF_AMDGPU_MACH);
595 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1031, EF_AMDGPU_MACH);
596 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1032, EF_AMDGPU_MACH);
597 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1033, EF_AMDGPU_MACH);
598 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1034, EF_AMDGPU_MACH);
599 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1035, EF_AMDGPU_MACH);
600 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1036, EF_AMDGPU_MACH);
601 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1100, EF_AMDGPU_MACH);
602 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1101, EF_AMDGPU_MACH);
603 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1102, EF_AMDGPU_MACH);
604 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1103, EF_AMDGPU_MACH);
605 switch (Object->Header.ABIVersion) {
606 default:
607 // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags.
608 [[fallthrough]];
609 case ELF::ELFABIVERSION_AMDGPU_HSA_V3:
610 BCase(EF_AMDGPU_FEATURE_XNACK_V3);
611 BCase(EF_AMDGPU_FEATURE_SRAMECC_V3);
612 break;
613 case ELF::ELFABIVERSION_AMDGPU_HSA_V4:
614 case ELF::ELFABIVERSION_AMDGPU_HSA_V5:
615 BCaseMask(EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4,
616 EF_AMDGPU_FEATURE_XNACK_V4);
617 BCaseMask(EF_AMDGPU_FEATURE_XNACK_ANY_V4,
618 EF_AMDGPU_FEATURE_XNACK_V4);
619 BCaseMask(EF_AMDGPU_FEATURE_XNACK_OFF_V4,
620 EF_AMDGPU_FEATURE_XNACK_V4);
621 BCaseMask(EF_AMDGPU_FEATURE_XNACK_ON_V4,
622 EF_AMDGPU_FEATURE_XNACK_V4);
623 BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4,
624 EF_AMDGPU_FEATURE_SRAMECC_V4);
625 BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_ANY_V4,
626 EF_AMDGPU_FEATURE_SRAMECC_V4);
627 BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_OFF_V4,
628 EF_AMDGPU_FEATURE_SRAMECC_V4);
629 BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_ON_V4,
630 EF_AMDGPU_FEATURE_SRAMECC_V4);
631 break;
632 }
633 break;
634 default:
635 break;
636 }
637#undef BCase
638#undef BCaseMask
639}
640
641void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
642 IO &IO, ELFYAML::ELF_SHT &Value) {
643 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
644 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", 644, __extension__ __PRETTY_FUNCTION__
))
;
645#define ECase(X) IO.enumCase(Value, #X, ELF::X)
646 ECase(SHT_NULL);
647 ECase(SHT_PROGBITS);
648 ECase(SHT_SYMTAB);
649 // FIXME: Issue a diagnostic with this information.
650 ECase(SHT_STRTAB);
651 ECase(SHT_RELA);
652 ECase(SHT_HASH);
653 ECase(SHT_DYNAMIC);
654 ECase(SHT_NOTE);
655 ECase(SHT_NOBITS);
656 ECase(SHT_REL);
657 ECase(SHT_SHLIB);
658 ECase(SHT_DYNSYM);
659 ECase(SHT_INIT_ARRAY);
660 ECase(SHT_FINI_ARRAY);
661 ECase(SHT_PREINIT_ARRAY);
662 ECase(SHT_GROUP);
663 ECase(SHT_SYMTAB_SHNDX);
664 ECase(SHT_RELR);
665 ECase(SHT_ANDROID_REL);
666 ECase(SHT_ANDROID_RELA);
667 ECase(SHT_ANDROID_RELR);
668 ECase(SHT_LLVM_ODRTAB);
669 ECase(SHT_LLVM_LINKER_OPTIONS);
670 ECase(SHT_LLVM_CALL_GRAPH_PROFILE);
671 ECase(SHT_LLVM_ADDRSIG);
672 ECase(SHT_LLVM_DEPENDENT_LIBRARIES);
673 ECase(SHT_LLVM_SYMPART);
674 ECase(SHT_LLVM_PART_EHDR);
675 ECase(SHT_LLVM_PART_PHDR);
676 ECase(SHT_LLVM_BB_ADDR_MAP_V0);
677 ECase(SHT_LLVM_BB_ADDR_MAP);
678 ECase(SHT_LLVM_OFFLOADING);
679 ECase(SHT_GNU_ATTRIBUTES);
680 ECase(SHT_GNU_HASH);
681 ECase(SHT_GNU_verdef);
682 ECase(SHT_GNU_verneed);
683 ECase(SHT_GNU_versym);
684 switch (Object->getMachine()) {
685 case ELF::EM_ARM:
686 ECase(SHT_ARM_EXIDX);
687 ECase(SHT_ARM_PREEMPTMAP);
688 ECase(SHT_ARM_ATTRIBUTES);
689 ECase(SHT_ARM_DEBUGOVERLAY);
690 ECase(SHT_ARM_OVERLAYSECTION);
691 break;
692 case ELF::EM_HEXAGON:
693 ECase(SHT_HEX_ORDERED);
694 break;
695 case ELF::EM_X86_64:
696 ECase(SHT_X86_64_UNWIND);
697 break;
698 case ELF::EM_MIPS:
699 ECase(SHT_MIPS_REGINFO);
700 ECase(SHT_MIPS_OPTIONS);
701 ECase(SHT_MIPS_DWARF);
702 ECase(SHT_MIPS_ABIFLAGS);
703 break;
704 case ELF::EM_RISCV:
705 ECase(SHT_RISCV_ATTRIBUTES);
706 break;
707 case ELF::EM_MSP430:
708 ECase(SHT_MSP430_ATTRIBUTES);
709 break;
710 default:
711 // Nothing to do.
712 break;
713 }
714#undef ECase
715 IO.enumFallback<Hex32>(Value);
716}
717
718void ScalarBitSetTraits<ELFYAML::ELF_PF>::bitset(IO &IO,
719 ELFYAML::ELF_PF &Value) {
720#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
721 BCase(PF_X);
722 BCase(PF_W);
723 BCase(PF_R);
724}
725
726void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
727 ELFYAML::ELF_SHF &Value) {
728 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
729#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
730 BCase(SHF_WRITE);
731 BCase(SHF_ALLOC);
732 BCase(SHF_EXCLUDE);
733 BCase(SHF_EXECINSTR);
734 BCase(SHF_MERGE);
735 BCase(SHF_STRINGS);
736 BCase(SHF_INFO_LINK);
737 BCase(SHF_LINK_ORDER);
738 BCase(SHF_OS_NONCONFORMING);
739 BCase(SHF_GROUP);
740 BCase(SHF_TLS);
741 BCase(SHF_COMPRESSED);
742 switch (Object->getOSAbi()) {
743 case ELF::ELFOSABI_SOLARIS:
744 BCase(SHF_SUNW_NODISCARD);
745 break;
746 default:
747 BCase(SHF_GNU_RETAIN);
748 break;
749 }
750 switch (Object->getMachine()) {
751 case ELF::EM_ARM:
752 BCase(SHF_ARM_PURECODE);
753 break;
754 case ELF::EM_HEXAGON:
755 BCase(SHF_HEX_GPREL);
756 break;
757 case ELF::EM_MIPS:
758 BCase(SHF_MIPS_NODUPES);
759 BCase(SHF_MIPS_NAMES);
760 BCase(SHF_MIPS_LOCAL);
761 BCase(SHF_MIPS_NOSTRIP);
762 BCase(SHF_MIPS_GPREL);
763 BCase(SHF_MIPS_MERGE);
764 BCase(SHF_MIPS_ADDR);
765 BCase(SHF_MIPS_STRING);
766 break;
767 case ELF::EM_X86_64:
768 BCase(SHF_X86_64_LARGE);
769 break;
770 default:
771 // Nothing to do.
772 break;
773 }
774#undef BCase
775}
776
777void ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration(
778 IO &IO, ELFYAML::ELF_SHN &Value) {
779 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
780 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", 780, __extension__ __PRETTY_FUNCTION__
))
;
781#define ECase(X) IO.enumCase(Value, #X, ELF::X)
782 ECase(SHN_UNDEF);
783 ECase(SHN_LORESERVE);
784 ECase(SHN_LOPROC);
785 ECase(SHN_HIPROC);
786 ECase(SHN_LOOS);
787 ECase(SHN_HIOS);
788 ECase(SHN_ABS);
789 ECase(SHN_COMMON);
790 ECase(SHN_XINDEX);
791 ECase(SHN_HIRESERVE);
792 ECase(SHN_AMDGPU_LDS);
793
794 if (!IO.outputting() || Object->getMachine() == ELF::EM_MIPS) {
795 ECase(SHN_MIPS_ACOMMON);
796 ECase(SHN_MIPS_TEXT);
797 ECase(SHN_MIPS_DATA);
798 ECase(SHN_MIPS_SCOMMON);
799 ECase(SHN_MIPS_SUNDEFINED);
800 }
801
802 ECase(SHN_HEXAGON_SCOMMON);
803 ECase(SHN_HEXAGON_SCOMMON_1);
804 ECase(SHN_HEXAGON_SCOMMON_2);
805 ECase(SHN_HEXAGON_SCOMMON_4);
806 ECase(SHN_HEXAGON_SCOMMON_8);
807#undef ECase
808 IO.enumFallback<Hex16>(Value);
809}
810
811void ScalarEnumerationTraits<ELFYAML::ELF_STB>::enumeration(
812 IO &IO, ELFYAML::ELF_STB &Value) {
813#define ECase(X) IO.enumCase(Value, #X, ELF::X)
814 ECase(STB_LOCAL);
815 ECase(STB_GLOBAL);
816 ECase(STB_WEAK);
817 ECase(STB_GNU_UNIQUE);
818#undef ECase
819 IO.enumFallback<Hex8>(Value);
820}
821
822void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
823 IO &IO, ELFYAML::ELF_STT &Value) {
824#define ECase(X) IO.enumCase(Value, #X, ELF::X)
825 ECase(STT_NOTYPE);
826 ECase(STT_OBJECT);
827 ECase(STT_FUNC);
828 ECase(STT_SECTION);
829 ECase(STT_FILE);
830 ECase(STT_COMMON);
831 ECase(STT_TLS);
832 ECase(STT_GNU_IFUNC);
833#undef ECase
834 IO.enumFallback<Hex8>(Value);
835}
836
837
838void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration(
839 IO &IO, ELFYAML::ELF_RSS &Value) {
840#define ECase(X) IO.enumCase(Value, #X, ELF::X)
841 ECase(RSS_UNDEF);
842 ECase(RSS_GP);
843 ECase(RSS_GP0);
844 ECase(RSS_LOC);
845#undef ECase
846}
847
848void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
849 IO &IO, ELFYAML::ELF_REL &Value) {
850 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
851 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", 851, __extension__ __PRETTY_FUNCTION__
))
;
852#define ELF_RELOC(X, Y) IO.enumCase(Value, #X, ELF::X);
853 switch (Object->getMachine()) {
854 case ELF::EM_X86_64:
855#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
856 break;
857 case ELF::EM_MIPS:
858#include "llvm/BinaryFormat/ELFRelocs/Mips.def"
859 break;
860 case ELF::EM_HEXAGON:
861#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
862 break;
863 case ELF::EM_386:
864 case ELF::EM_IAMCU:
865#include "llvm/BinaryFormat/ELFRelocs/i386.def"
866 break;
867 case ELF::EM_AARCH64:
868#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
869 break;
870 case ELF::EM_ARM:
871#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
872 break;
873 case ELF::EM_ARC:
874#include "llvm/BinaryFormat/ELFRelocs/ARC.def"
875 break;
876 case ELF::EM_RISCV:
877#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
878 break;
879 case ELF::EM_LANAI:
880#include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
881 break;
882 case ELF::EM_AMDGPU:
883#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
884 break;
885 case ELF::EM_BPF:
886#include "llvm/BinaryFormat/ELFRelocs/BPF.def"
887 break;
888 case ELF::EM_VE:
889#include "llvm/BinaryFormat/ELFRelocs/VE.def"
890 break;
891 case ELF::EM_CSKY:
892#include "llvm/BinaryFormat/ELFRelocs/CSKY.def"
893 break;
894 case ELF::EM_PPC:
895#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
896 break;
897 case ELF::EM_PPC64:
898#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
899 break;
900 case ELF::EM_68K:
901#include "llvm/BinaryFormat/ELFRelocs/M68k.def"
902 break;
903 case ELF::EM_LOONGARCH:
904#include "llvm/BinaryFormat/ELFRelocs/LoongArch.def"
905 break;
906 case ELF::EM_XTENSA:
907#include "llvm/BinaryFormat/ELFRelocs/Xtensa.def"
908 break;
909 default:
910 // Nothing to do.
911 break;
912 }
913#undef ELF_RELOC
914 IO.enumFallback<Hex32>(Value);
915}
916
917void ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG>::enumeration(
918 IO &IO, ELFYAML::ELF_DYNTAG &Value) {
919 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
920 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", 920, __extension__ __PRETTY_FUNCTION__
))
;
921
922// Disable architecture specific tags by default. We might enable them below.
923#define AARCH64_DYNAMIC_TAG(name, value)
924#define MIPS_DYNAMIC_TAG(name, value)
925#define HEXAGON_DYNAMIC_TAG(name, value)
926#define PPC_DYNAMIC_TAG(name, value)
927#define PPC64_DYNAMIC_TAG(name, value)
928// Ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
929#define DYNAMIC_TAG_MARKER(name, value)
930
931#define STRINGIFY(X) (#X)
932#define DYNAMIC_TAG(X, Y) IO.enumCase(Value, STRINGIFY(DT_##X), ELF::DT_##X);
933 switch (Object->getMachine()) {
934 case ELF::EM_AARCH64:
935#undef AARCH64_DYNAMIC_TAG
936#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
937#include "llvm/BinaryFormat/DynamicTags.def"
938#undef AARCH64_DYNAMIC_TAG
939#define AARCH64_DYNAMIC_TAG(name, value)
940 break;
941 case ELF::EM_MIPS:
942#undef MIPS_DYNAMIC_TAG
943#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
944#include "llvm/BinaryFormat/DynamicTags.def"
945#undef MIPS_DYNAMIC_TAG
946#define MIPS_DYNAMIC_TAG(name, value)
947 break;
948 case ELF::EM_HEXAGON:
949#undef HEXAGON_DYNAMIC_TAG
950#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
951#include "llvm/BinaryFormat/DynamicTags.def"
952#undef HEXAGON_DYNAMIC_TAG
953#define HEXAGON_DYNAMIC_TAG(name, value)
954 break;
955 case ELF::EM_PPC:
956#undef PPC_DYNAMIC_TAG
957#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
958#include "llvm/BinaryFormat/DynamicTags.def"
959#undef PPC_DYNAMIC_TAG
960#define PPC_DYNAMIC_TAG(name, value)
961 break;
962 case ELF::EM_PPC64:
963#undef PPC64_DYNAMIC_TAG
964#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
965#include "llvm/BinaryFormat/DynamicTags.def"
966#undef PPC64_DYNAMIC_TAG
967#define PPC64_DYNAMIC_TAG(name, value)
968 break;
969 case ELF::EM_RISCV:
970#undef RISCV_DYNAMIC_TAG
971#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
972#include "llvm/BinaryFormat/DynamicTags.def"
973#undef RISCV_DYNAMIC_TAG
974#define RISCV_DYNAMIC_TAG(name, value)
975 break;
976 default:
977#include "llvm/BinaryFormat/DynamicTags.def"
978 break;
979 }
980#undef AARCH64_DYNAMIC_TAG
981#undef MIPS_DYNAMIC_TAG
982#undef HEXAGON_DYNAMIC_TAG
983#undef PPC_DYNAMIC_TAG
984#undef PPC64_DYNAMIC_TAG
985#undef DYNAMIC_TAG_MARKER
986#undef STRINGIFY
987#undef DYNAMIC_TAG
988
989 IO.enumFallback<Hex64>(Value);
990}
991
992void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration(
993 IO &IO, ELFYAML::MIPS_AFL_REG &Value) {
994#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X)
995 ECase(REG_NONE);
996 ECase(REG_32);
997 ECase(REG_64);
998 ECase(REG_128);
999#undef ECase
1000}
1001
1002void ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP>::enumeration(
1003 IO &IO, ELFYAML::MIPS_ABI_FP &Value) {
1004#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X)
1005 ECase(FP_ANY);
1006 ECase(FP_DOUBLE);
1007 ECase(FP_SINGLE);
1008 ECase(FP_SOFT);
1009 ECase(FP_OLD_64);
1010 ECase(FP_XX);
1011 ECase(FP_64);
1012 ECase(FP_64A);
1013#undef ECase
1014}
1015
1016void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT>::enumeration(
1017 IO &IO, ELFYAML::MIPS_AFL_EXT &Value) {
1018#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X)
1019 ECase(EXT_NONE);
1020 ECase(EXT_XLR);
1021 ECase(EXT_OCTEON2);
1022 ECase(EXT_OCTEONP);
1023 ECase(EXT_LOONGSON_3A);
1024 ECase(EXT_OCTEON);
1025 ECase(EXT_5900);
1026 ECase(EXT_4650);
1027 ECase(EXT_4010);
1028 ECase(EXT_4100);
1029 ECase(EXT_3900);
1030 ECase(EXT_10000);
1031 ECase(EXT_SB1);
1032 ECase(EXT_4111);
1033 ECase(EXT_4120);
1034 ECase(EXT_5400);
1035 ECase(EXT_5500);
1036 ECase(EXT_LOONGSON_2E);
1037 ECase(EXT_LOONGSON_2F);
1038 ECase(EXT_OCTEON3);
1039#undef ECase
1040}
1041
1042void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration(
1043 IO &IO, ELFYAML::MIPS_ISA &Value) {
1044 IO.enumCase(Value, "MIPS1", 1);
1045 IO.enumCase(Value, "MIPS2", 2);
1046 IO.enumCase(Value, "MIPS3", 3);
1047 IO.enumCase(Value, "MIPS4", 4);
1048 IO.enumCase(Value, "MIPS5", 5);
1049 IO.enumCase(Value, "MIPS32", 32);
1050 IO.enumCase(Value, "MIPS64", 64);
1051 IO.enumFallback<Hex32>(Value);
1052}
1053
1054void ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE>::bitset(
1055 IO &IO, ELFYAML::MIPS_AFL_ASE &Value) {
1056#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X)
1057 BCase(DSP);
1058 BCase(DSPR2);
1059 BCase(EVA);
1060 BCase(MCU);
1061 BCase(MDMX);
1062 BCase(MIPS3D);
1063 BCase(MT);
1064 BCase(SMARTMIPS);
1065 BCase(VIRT);
1066 BCase(MSA);
1067 BCase(MIPS16);
1068 BCase(MICROMIPS);
1069 BCase(XPA);
1070 BCase(CRC);
1071 BCase(GINV);
1072#undef BCase
1073}
1074
1075void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset(
1076 IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value) {
1077#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X)
1078 BCase(ODDSPREG);
1079#undef BCase
1080}
1081
1082void MappingTraits<ELFYAML::SectionHeader>::mapping(
1083 IO &IO, ELFYAML::SectionHeader &SHdr) {
1084 IO.mapRequired("Name", SHdr.Name);
1085}
1086
1087void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
1088 ELFYAML::FileHeader &FileHdr) {
1089 IO.mapRequired("Class", FileHdr.Class);
1090 IO.mapRequired("Data", FileHdr.Data);
1091 IO.mapOptional("OSABI", FileHdr.OSABI, ELFYAML::ELF_ELFOSABI(0));
1092 IO.mapOptional("ABIVersion", FileHdr.ABIVersion, Hex8(0));
1093 IO.mapRequired("Type", FileHdr.Type);
1094 IO.mapOptional("Machine", FileHdr.Machine);
1095 IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
1096 IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
1097 IO.mapOptional("SectionHeaderStringTable", FileHdr.SectionHeaderStringTable);
1098
1099 // obj2yaml does not dump these fields.
1100 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", 1101, __extension__ __PRETTY_FUNCTION__
))
1101 (!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", 1101, __extension__ __PRETTY_FUNCTION__
))
;
1102 IO.mapOptional("EPhOff", FileHdr.EPhOff);
1103 IO.mapOptional("EPhEntSize", FileHdr.EPhEntSize);
1104 IO.mapOptional("EPhNum", FileHdr.EPhNum);
1105 IO.mapOptional("EShEntSize", FileHdr.EShEntSize);
1106 IO.mapOptional("EShOff", FileHdr.EShOff);
1107 IO.mapOptional("EShNum", FileHdr.EShNum);
1108 IO.mapOptional("EShStrNdx", FileHdr.EShStrNdx);
1109}
1110
1111void MappingTraits<ELFYAML::ProgramHeader>::mapping(
1112 IO &IO, ELFYAML::ProgramHeader &Phdr) {
1113 IO.mapRequired("Type", Phdr.Type);
1114 IO.mapOptional("Flags", Phdr.Flags, ELFYAML::ELF_PF(0));
1115 IO.mapOptional("FirstSec", Phdr.FirstSec);
1116 IO.mapOptional("LastSec", Phdr.LastSec);
1117 IO.mapOptional("VAddr", Phdr.VAddr, Hex64(0));
1118 IO.mapOptional("PAddr", Phdr.PAddr, Phdr.VAddr);
1119 IO.mapOptional("Align", Phdr.Align);
1120 IO.mapOptional("FileSize", Phdr.FileSize);
1121 IO.mapOptional("MemSize", Phdr.MemSize);
1122 IO.mapOptional("Offset", Phdr.Offset);
1123}
1124
1125std::string MappingTraits<ELFYAML::ProgramHeader>::validate(
1126 IO &IO, ELFYAML::ProgramHeader &FileHdr) {
1127 if (!FileHdr.FirstSec && FileHdr.LastSec)
1128 return "the \"LastSec\" key can't be used without the \"FirstSec\" key";
1129 if (FileHdr.FirstSec && !FileHdr.LastSec)
1130 return "the \"FirstSec\" key can't be used without the \"LastSec\" key";
1131 return "";
1132}
1133
1134LLVM_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
; };
1135
1136template <> struct ScalarTraits<StOtherPiece> {
1137 static void output(const StOtherPiece &Val, void *, raw_ostream &Out) {
1138 Out << Val;
1139 }
1140 static StringRef input(StringRef Scalar, void *, StOtherPiece &Val) {
1141 Val = Scalar;
1142 return {};
1143 }
1144 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1145};
1146template <> struct SequenceElementTraits<StOtherPiece> {
1147 static const bool flow = true;
1148};
1149
1150template <> struct ScalarTraits<ELFYAML::YAMLFlowString> {
1151 static void output(const ELFYAML::YAMLFlowString &Val, void *,
1152 raw_ostream &Out) {
1153 Out << Val;
1154 }
1155 static StringRef input(StringRef Scalar, void *,
1156 ELFYAML::YAMLFlowString &Val) {
1157 Val = Scalar;
1158 return {};
1159 }
1160 static QuotingType mustQuote(StringRef S) {
1161 return ScalarTraits<StringRef>::mustQuote(S);
1162 }
1163};
1164template <> struct SequenceElementTraits<ELFYAML::YAMLFlowString> {
1165 static const bool flow = true;
1166};
1167
1168namespace {
1169
1170struct NormalizedOther {
1171 NormalizedOther(IO &IO) : YamlIO(IO) {}
1172 NormalizedOther(IO &IO, std::optional<uint8_t> Original) : YamlIO(IO) {
1173 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", 1174, __extension__ __PRETTY_FUNCTION__
))
1174 "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", 1174, __extension__ __PRETTY_FUNCTION__
))
;
1175 std::vector<StOtherPiece> Ret;
1176 const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext());
1177 for (std::pair<StringRef, uint8_t> &P :
1178 getFlags(Object->getMachine()).takeVector()) {
1179 uint8_t FlagValue = P.second;
1180 if ((*Original & FlagValue) != FlagValue)
1181 continue;
1182 *Original &= ~FlagValue;
1183 Ret.push_back({P.first});
1184 }
1185
1186 if (*Original != 0) {
1187 UnknownFlagsHolder = std::to_string(*Original);
1188 Ret.push_back({UnknownFlagsHolder});
1189 }
1190
1191 if (!Ret.empty())
1192 Other = std::move(Ret);
1193 }
1194
1195 uint8_t toValue(StringRef Name) {
1196 const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext());
1197 MapVector<StringRef, uint8_t> Flags = getFlags(Object->getMachine());
1198
1199 auto It = Flags.find(Name);
1200 if (It != Flags.end())
1201 return It->second;
1202
1203 uint8_t Val;
1204 if (to_integer(Name, Val))
1205 return Val;
1206
1207 YamlIO.setError("an unknown value is used for symbol's 'Other' field: " +
1208 Name);
1209 return 0;
1210 }
1211
1212 std::optional<uint8_t> denormalize(IO &) {
1213 if (!Other)
1214 return std::nullopt;
1215 uint8_t Ret = 0;
1216 for (StOtherPiece &Val : *Other)
1217 Ret |= toValue(Val);
1218 return Ret;
1219 }
1220
1221 // st_other field is used to encode symbol visibility and platform-dependent
1222 // flags and values. This method returns a name to value map that is used for
1223 // parsing and encoding this field.
1224 MapVector<StringRef, uint8_t> getFlags(unsigned EMachine) {
1225 MapVector<StringRef, uint8_t> Map;
1226 // STV_* values are just enumeration values. We add them in a reversed order
1227 // because when we convert the st_other to named constants when printing
1228 // YAML we want to use a maximum number of bits on each step:
1229 // when we have st_other == 3, we want to print it as STV_PROTECTED (3), but
1230 // not as STV_HIDDEN (2) + STV_INTERNAL (1).
1231 Map["STV_PROTECTED"] = ELF::STV_PROTECTED;
1232 Map["STV_HIDDEN"] = ELF::STV_HIDDEN;
1233 Map["STV_INTERNAL"] = ELF::STV_INTERNAL;
1234 // STV_DEFAULT is used to represent the default visibility and has a value
1235 // 0. We want to be able to read it from YAML documents, but there is no
1236 // reason to print it.
1237 if (!YamlIO.outputting())
1238 Map["STV_DEFAULT"] = ELF::STV_DEFAULT;
1239
1240 // MIPS is not consistent. All of the STO_MIPS_* values are bit flags,
1241 // except STO_MIPS_MIPS16 which overlaps them. It should be checked and
1242 // consumed first when we print the output, because we do not want to print
1243 // any other flags that have the same bits instead.
1244 if (EMachine == ELF::EM_MIPS) {
1245 Map["STO_MIPS_MIPS16"] = ELF::STO_MIPS_MIPS16;
1246 Map["STO_MIPS_MICROMIPS"] = ELF::STO_MIPS_MICROMIPS;
1247 Map["STO_MIPS_PIC"] = ELF::STO_MIPS_PIC;
1248 Map["STO_MIPS_PLT"] = ELF::STO_MIPS_PLT;
1249 Map["STO_MIPS_OPTIONAL"] = ELF::STO_MIPS_OPTIONAL;
1250 }
1251
1252 if (EMachine == ELF::EM_AARCH64)
1253 Map["STO_AARCH64_VARIANT_PCS"] = ELF::STO_AARCH64_VARIANT_PCS;
1254 if (EMachine == ELF::EM_RISCV)
1255 Map["STO_RISCV_VARIANT_CC"] = ELF::STO_RISCV_VARIANT_CC;
1256 return Map;
1257 }
1258
1259 IO &YamlIO;
1260 std::optional<std::vector<StOtherPiece>> Other;
1261 std::string UnknownFlagsHolder;
1262};
1263
1264} // end anonymous namespace
1265
1266void ScalarTraits<ELFYAML::YAMLIntUInt>::output(const ELFYAML::YAMLIntUInt &Val,
1267 void *Ctx, raw_ostream &Out) {
1268 Out << Val;
1269}
1270
1271StringRef ScalarTraits<ELFYAML::YAMLIntUInt>::input(StringRef Scalar, void *Ctx,
1272 ELFYAML::YAMLIntUInt &Val) {
1273 const bool Is64 = static_cast<ELFYAML::Object *>(Ctx)->Header.Class ==
1274 ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
1275 StringRef ErrMsg = "invalid number";
1276 // We do not accept negative hex numbers because their meaning is ambiguous.
1277 // For example, would -0xfffffffff mean 1 or INT32_MIN?
1278 if (Scalar.empty() || Scalar.startswith("-0x"))
1279 return ErrMsg;
1280
1281 if (Scalar.startswith("-")) {
1282 const int64_t MinVal = Is64 ? INT64_MIN(-9223372036854775807L -1) : INT32_MIN(-2147483647-1);
1283 long long Int;
1284 if (getAsSignedInteger(Scalar, /*Radix=*/0, Int) || (Int < MinVal))
1285 return ErrMsg;
1286 Val = Int;
1287 return "";
1288 }
1289
1290 const uint64_t MaxVal = Is64 ? UINT64_MAX(18446744073709551615UL) : UINT32_MAX(4294967295U);
1291 unsigned long long UInt;
1292 if (getAsUnsignedInteger(Scalar, /*Radix=*/0, UInt) || (UInt > MaxVal))
1293 return ErrMsg;
1294 Val = UInt;
1295 return "";
1296}
1297
1298void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
1299 IO.mapOptional("Name", Symbol.Name, StringRef());
1300 IO.mapOptional("StName", Symbol.StName);
1301 IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
1302 IO.mapOptional("Section", Symbol.Section);
1303 IO.mapOptional("Index", Symbol.Index);
1304 IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0));
1305 IO.mapOptional("Value", Symbol.Value);
1306 IO.mapOptional("Size", Symbol.Size);
1307
1308 // Symbol's Other field is a bit special. It is usually a field that
1309 // represents st_other and holds the symbol visibility. However, on some
1310 // platforms, it can contain bit fields and regular values, or even sometimes
1311 // a crazy mix of them (see comments for NormalizedOther). Because of this, we
1312 // need special handling.
1313 MappingNormalization<NormalizedOther, std::optional<uint8_t>> Keys(
1314 IO, Symbol.Other);
1315 IO.mapOptional("Other", Keys->Other);
1316}
1317
1318std::string MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
1319 ELFYAML::Symbol &Symbol) {
1320 if (Symbol.Index && Symbol.Section)
1321 return "Index and Section cannot both be specified for Symbol";
1322 return "";
1323}
1324
1325static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
1326 IO.mapOptional("Name", Section.Name, StringRef());
1327 IO.mapRequired("Type", Section.Type);
1328 IO.mapOptional("Flags", Section.Flags);
1329 IO.mapOptional("Address", Section.Address);
1330 IO.mapOptional("Link", Section.Link);
1331 IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
1332 IO.mapOptional("EntSize", Section.EntSize);
1333 IO.mapOptional("Offset", Section.Offset);
1334
1335 IO.mapOptional("Content", Section.Content);
1336 IO.mapOptional("Size", Section.Size);
1337
1338 // obj2yaml does not dump these fields. They are expected to be empty when we
1339 // are producing YAML, because yaml2obj sets appropriate values for them
1340 // automatically when they are not explicitly defined.
1341 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", 1343, __extension__ __PRETTY_FUNCTION__
))
1342 (!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", 1343, __extension__ __PRETTY_FUNCTION__
))
1343 !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", 1343, __extension__ __PRETTY_FUNCTION__
))
;
1344 IO.mapOptional("ShAddrAlign", Section.ShAddrAlign);
1345 IO.mapOptional("ShName", Section.ShName);
1346 IO.mapOptional("ShOffset", Section.ShOffset);
1347 IO.mapOptional("ShSize", Section.ShSize);
1348 IO.mapOptional("ShFlags", Section.ShFlags);
1349 IO.mapOptional("ShType", Section.ShType);
1350}
1351
1352static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
1353 commonSectionMapping(IO, Section);
1354 IO.mapOptional("Entries", Section.Entries);
1355}
1356
1357static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
1358 commonSectionMapping(IO, Section);
1359
1360 // We also support reading a content as array of bytes using the ContentArray
1361 // key. obj2yaml never prints this field.
1362 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", 1362, __extension__ __PRETTY_FUNCTION__
))
;
1363 IO.mapOptional("ContentArray", Section.ContentBuf);
1364 if (Section.ContentBuf) {
1365 if (Section.Content)
1366 IO.setError("Content and ContentArray can't be used together");
1367 Section.Content = yaml::BinaryRef(*Section.ContentBuf);
1368 }
1369
1370 IO.mapOptional("Info", Section.Info);
1371}
1372
1373static void sectionMapping(IO &IO, ELFYAML::BBAddrMapSection &Section) {
1374 commonSectionMapping(IO, Section);
1375 IO.mapOptional("Content", Section.Content);
1376 IO.mapOptional("Entries", Section.Entries);
1377}
1378
1379static void sectionMapping(IO &IO, ELFYAML::StackSizesSection &Section) {
1380 commonSectionMapping(IO, Section);
1381 IO.mapOptional("Entries", Section.Entries);
1382}
1383
1384static void sectionMapping(IO &IO, ELFYAML::HashSection &Section) {
1385 commonSectionMapping(IO, Section);
1386 IO.mapOptional("Bucket", Section.Bucket);
1387 IO.mapOptional("Chain", Section.Chain);
1388
1389 // obj2yaml does not dump these fields. They can be used to override nchain
1390 // and nbucket values for creating broken sections.
1391 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", 1391, __extension__ __PRETTY_FUNCTION__
))
;
1392 IO.mapOptional("NChain", Section.NChain);
1393 IO.mapOptional("NBucket", Section.NBucket);
1394}
1395
1396static void sectionMapping(IO &IO, ELFYAML::NoteSection &Section) {
1397 commonSectionMapping(IO, Section);
1398 IO.mapOptional("Notes", Section.Notes);
1399}
1400
1401
1402static void sectionMapping(IO &IO, ELFYAML::GnuHashSection &Section) {
1403 commonSectionMapping(IO, Section);
1404 IO.mapOptional("Header", Section.Header);
1405 IO.mapOptional("BloomFilter", Section.BloomFilter);
1406 IO.mapOptional("HashBuckets", Section.HashBuckets);
1407 IO.mapOptional("HashValues", Section.HashValues);
1408}
1409static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
1410 commonSectionMapping(IO, Section);
1411}
1412
1413static void sectionMapping(IO &IO, ELFYAML::VerdefSection &Section) {
1414 commonSectionMapping(IO, Section);
1415 IO.mapOptional("Info", Section.Info);
1416 IO.mapOptional("Entries", Section.Entries);
1417}
1418
1419static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
1420 commonSectionMapping(IO, Section);
1421 IO.mapOptional("Entries", Section.Entries);
1422}
1423
1424static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) {
1425 commonSectionMapping(IO, Section);
1426 IO.mapOptional("Info", Section.Info);
1427 IO.mapOptional("Dependencies", Section.VerneedV);
1428}
1429
1430static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
1431 commonSectionMapping(IO, Section);
1432 IO.mapOptional("Info", Section.RelocatableSec, StringRef());
1433 IO.mapOptional("Relocations", Section.Relocations);
1434}
1435
1436static void sectionMapping(IO &IO, ELFYAML::RelrSection &Section) {
1437 commonSectionMapping(IO, Section);
1438 IO.mapOptional("Entries", Section.Entries);
1439}
1440
1441static void groupSectionMapping(IO &IO, ELFYAML::GroupSection &Group) {
1442 commonSectionMapping(IO, Group);
1443 IO.mapOptional("Info", Group.Signature);
1444 IO.mapOptional("Members", Group.Members);
1445}
1446
1447static void sectionMapping(IO &IO, ELFYAML::SymtabShndxSection &Section) {
1448 commonSectionMapping(IO, Section);
1449 IO.mapOptional("Entries", Section.Entries);
1450}
1451
1452static void sectionMapping(IO &IO, ELFYAML::AddrsigSection &Section) {
1453 commonSectionMapping(IO, Section);
1454 IO.mapOptional("Symbols", Section.Symbols);
1455}
1456
1457static void fillMapping(IO &IO, ELFYAML::Fill &Fill) {
1458 IO.mapOptional("Name", Fill.Name, StringRef());
1459 IO.mapOptional("Pattern", Fill.Pattern);
1460 IO.mapOptional("Offset", Fill.Offset);
1461 IO.mapRequired("Size", Fill.Size);
1462}
1463
1464static void sectionHeaderTableMapping(IO &IO,
1465 ELFYAML::SectionHeaderTable &SHT) {
1466 IO.mapOptional("Offset", SHT.Offset);
1467 IO.mapOptional("Sections", SHT.Sections);
1468 IO.mapOptional("Excluded", SHT.Excluded);
1469 IO.mapOptional("NoHeaders", SHT.NoHeaders);
1470}
1471
1472static void sectionMapping(IO &IO, ELFYAML::LinkerOptionsSection &Section) {
1473 commonSectionMapping(IO, Section);
1474 IO.mapOptional("Options", Section.Options);
1475}
1476
1477static void sectionMapping(IO &IO,
1478 ELFYAML::DependentLibrariesSection &Section) {
1479 commonSectionMapping(IO, Section);
1480 IO.mapOptional("Libraries", Section.Libs);
1481}
1482
1483static void sectionMapping(IO &IO, ELFYAML::CallGraphProfileSection &Section) {
1484 commonSectionMapping(IO, Section);
1485 IO.mapOptional("Entries", Section.Entries);
1486}
1487
1488void MappingTraits<ELFYAML::SectionOrType>::mapping(
1489 IO &IO, ELFYAML::SectionOrType &sectionOrType) {
1490 IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
1491}
1492
1493static void sectionMapping(IO &IO, ELFYAML::ARMIndexTableSection &Section) {
1494 commonSectionMapping(IO, Section);
1495 IO.mapOptional("Entries", Section.Entries);
1496}
1497
1498static void sectionMapping(IO &IO, ELFYAML::MipsABIFlags &Section) {
1499 commonSectionMapping(IO, Section);
1500 IO.mapOptional("Version", Section.Version, Hex16(0));
1501 IO.mapRequired("ISA", Section.ISALevel);
1502 IO.mapOptional("ISARevision", Section.ISARevision, Hex8(0));
1503 IO.mapOptional("ISAExtension", Section.ISAExtension,
1504 ELFYAML::MIPS_AFL_EXT(Mips::AFL_EXT_NONE));
1505 IO.mapOptional("ASEs", Section.ASEs, ELFYAML::MIPS_AFL_ASE(0));
1506 IO.mapOptional("FpABI", Section.FpABI,
1507 ELFYAML::MIPS_ABI_FP(Mips::Val_GNU_MIPS_ABI_FP_ANY));
1508 IO.mapOptional("GPRSize", Section.GPRSize,
1509 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1510 IO.mapOptional("CPR1Size", Section.CPR1Size,
1511 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1512 IO.mapOptional("CPR2Size", Section.CPR2Size,
1513 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1514 IO.mapOptional("Flags1", Section.Flags1, ELFYAML::MIPS_AFL_FLAGS1(0));
1515 IO.mapOptional("Flags2", Section.Flags2, Hex32(0));
1516}
1517
1518static StringRef getStringValue(IO &IO, const char *Key) {
1519 StringRef Val;
1520 IO.mapRequired(Key, Val);
1521 return Val;
1522}
1523
1524static void setStringValue(IO &IO, const char *Key, StringRef Val) {
1525 IO.mapRequired(Key, Val);
1526}
1527
1528static bool isInteger(StringRef Val) {
1529 APInt Tmp;
1530 return !Val.getAsInteger(0, Tmp);
1531}
1532
1533void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping(
1534 IO &IO, std::unique_ptr<ELFYAML::Chunk> &Section) {
1535 ELFYAML::ELF_SHT Type;
1
Calling defaulted default constructor for 'ELF_SHT'
3
Returning from default constructor for 'ELF_SHT'
1536 StringRef TypeStr;
1537 if (IO.outputting()) {
4
Assuming the condition is false
5
Taking false branch
1538 if (auto *S = dyn_cast<ELFYAML::Section>(Section.get()))
1539 Type = S->Type;
1540 else if (auto *SHT = dyn_cast<ELFYAML::SectionHeaderTable>(Section.get()))
1541 TypeStr = SHT->TypeStr;
1542 } else {
1543 // When the Type string does not have a "SHT_" prefix, we know it is not a
1544 // description of a regular ELF output section.
1545 TypeStr = getStringValue(IO, "Type");
1546 if (TypeStr.startswith("SHT_") || isInteger(TypeStr))
6
Assuming the condition is true
1547 IO.mapRequired("Type", Type);
7
Calling 'IO::mapRequired'
14
Returning from 'IO::mapRequired'
1548 }
1549
1550 if (TypeStr == "Fill") {
15
Assuming the condition is false
16
Taking false branch
1551 assert(!IO.outputting())(static_cast <bool> (!IO.outputting()) ? void (0) : __assert_fail
("!IO.outputting()", "llvm/lib/ObjectYAML/ELFYAML.cpp", 1551
, __extension__ __PRETTY_FUNCTION__))
; // We don't dump fills currently.
1552 Section.reset(new ELFYAML::Fill());
1553 fillMapping(IO, *cast<ELFYAML::Fill>(Section.get()));
1554 return;
1555 }
1556
1557 if (TypeStr == ELFYAML::SectionHeaderTable::TypeStr) {
17
Assuming the condition is false
18
Taking false branch
1558 if (IO.outputting())
1559 setStringValue(IO, "Type", TypeStr);
1560 else
1561 Section.reset(new ELFYAML::SectionHeaderTable(/*IsImplicit=*/false));
1562
1563 sectionHeaderTableMapping(
1564 IO, *cast<ELFYAML::SectionHeaderTable>(Section.get()));
1565 return;
1566 }
1567
1568 const auto &Obj = *static_cast<ELFYAML::Object *>(IO.getContext());
1569 if (Obj.getMachine() == ELF::EM_MIPS && Type == ELF::SHT_MIPS_ABIFLAGS) {
19
Assuming the condition is true
20
Calling 'ELF_SHT::operator=='
1570 if (!IO.outputting())
1571 Section.reset(new ELFYAML::MipsABIFlags());
1572 sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
1573 return;
1574 }
1575
1576 if (Obj.getMachine() == ELF::EM_ARM && Type == ELF::SHT_ARM_EXIDX) {
1577 if (!IO.outputting())
1578 Section.reset(new ELFYAML::ARMIndexTableSection());
1579 sectionMapping(IO, *cast<ELFYAML::ARMIndexTableSection>(Section.get()));
1580 return;
1581 }
1582
1583 switch (Type) {
1584 case ELF::SHT_DYNAMIC:
1585 if (!IO.outputting())
1586 Section.reset(new ELFYAML::DynamicSection());
1587 sectionMapping(IO, *cast<ELFYAML::DynamicSection>(Section.get()));
1588 break;
1589 case ELF::SHT_REL:
1590 case ELF::SHT_RELA:
1591 if (!IO.outputting())
1592 Section.reset(new ELFYAML::RelocationSection());
1593 sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
1594 break;
1595 case ELF::SHT_RELR:
1596 if (!IO.outputting())
1597 Section.reset(new ELFYAML::RelrSection());
1598 sectionMapping(IO, *cast<ELFYAML::RelrSection>(Section.get()));
1599 break;
1600 case ELF::SHT_GROUP:
1601 if (!IO.outputting())
1602 Section.reset(new ELFYAML::GroupSection());
1603 groupSectionMapping(IO, *cast<ELFYAML::GroupSection>(Section.get()));
1604 break;
1605 case ELF::SHT_NOBITS:
1606 if (!IO.outputting())
1607 Section.reset(new ELFYAML::NoBitsSection());
1608 sectionMapping(IO, *cast<ELFYAML::NoBitsSection>(Section.get()));
1609 break;
1610 case ELF::SHT_HASH:
1611 if (!IO.outputting())
1612 Section.reset(new ELFYAML::HashSection());
1613 sectionMapping(IO, *cast<ELFYAML::HashSection>(Section.get()));
1614 break;
1615 case ELF::SHT_NOTE:
1616 if (!IO.outputting())
1617 Section.reset(new ELFYAML::NoteSection());
1618 sectionMapping(IO, *cast<ELFYAML::NoteSection>(Section.get()));
1619 break;
1620 case ELF::SHT_GNU_HASH:
1621 if (!IO.outputting())
1622 Section.reset(new ELFYAML::GnuHashSection());
1623 sectionMapping(IO, *cast<ELFYAML::GnuHashSection>(Section.get()));
1624 break;
1625 case ELF::SHT_GNU_verdef:
1626 if (!IO.outputting())
1627 Section.reset(new ELFYAML::VerdefSection());
1628 sectionMapping(IO, *cast<ELFYAML::VerdefSection>(Section.get()));
1629 break;
1630 case ELF::SHT_GNU_versym:
1631 if (!IO.outputting())
1632 Section.reset(new ELFYAML::SymverSection());
1633 sectionMapping(IO, *cast<ELFYAML::SymverSection>(Section.get()));
1634 break;
1635 case ELF::SHT_GNU_verneed:
1636 if (!IO.outputting())
1637 Section.reset(new ELFYAML::VerneedSection());
1638 sectionMapping(IO, *cast<ELFYAML::VerneedSection>(Section.get()));
1639 break;
1640 case ELF::SHT_SYMTAB_SHNDX:
1641 if (!IO.outputting())
1642 Section.reset(new ELFYAML::SymtabShndxSection());
1643 sectionMapping(IO, *cast<ELFYAML::SymtabShndxSection>(Section.get()));
1644 break;
1645 case ELF::SHT_LLVM_ADDRSIG:
1646 if (!IO.outputting())
1647 Section.reset(new ELFYAML::AddrsigSection());
1648 sectionMapping(IO, *cast<ELFYAML::AddrsigSection>(Section.get()));
1649 break;
1650 case ELF::SHT_LLVM_LINKER_OPTIONS:
1651 if (!IO.outputting())
1652 Section.reset(new ELFYAML::LinkerOptionsSection());
1653 sectionMapping(IO, *cast<ELFYAML::LinkerOptionsSection>(Section.get()));
1654 break;
1655 case ELF::SHT_LLVM_DEPENDENT_LIBRARIES:
1656 if (!IO.outputting())
1657 Section.reset(new ELFYAML::DependentLibrariesSection());
1658 sectionMapping(IO,
1659 *cast<ELFYAML::DependentLibrariesSection>(Section.get()));
1660 break;
1661 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
1662 if (!IO.outputting())
1663 Section.reset(new ELFYAML::CallGraphProfileSection());
1664 sectionMapping(IO, *cast<ELFYAML::CallGraphProfileSection>(Section.get()));
1665 break;
1666 case ELF::SHT_LLVM_BB_ADDR_MAP_V0:
1667 case ELF::SHT_LLVM_BB_ADDR_MAP:
1668 if (!IO.outputting())
1669 Section.reset(new ELFYAML::BBAddrMapSection());
1670 sectionMapping(IO, *cast<ELFYAML::BBAddrMapSection>(Section.get()));
1671 break;
1672 default:
1673 if (!IO.outputting()) {
1674 StringRef Name;
1675 IO.mapOptional("Name", Name, StringRef());
1676 Name = ELFYAML::dropUniqueSuffix(Name);
1677
1678 if (ELFYAML::StackSizesSection::nameMatches(Name))
1679 Section = std::make_unique<ELFYAML::StackSizesSection>();
1680 else
1681 Section = std::make_unique<ELFYAML::RawContentSection>();
1682 }
1683
1684 if (auto S = dyn_cast<ELFYAML::RawContentSection>(Section.get()))
1685 sectionMapping(IO, *S);
1686 else
1687 sectionMapping(IO, *cast<ELFYAML::StackSizesSection>(Section.get()));
1688 }
1689}
1690
1691std::string MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
1692 IO &io, std::unique_ptr<ELFYAML::Chunk> &C) {
1693 if (const auto *F = dyn_cast<ELFYAML::Fill>(C.get())) {
1694 if (F->Pattern && F->Pattern->binary_size() != 0 && !F->Size)
1695 return "\"Size\" can't be 0 when \"Pattern\" is not empty";
1696 return "";
1697 }
1698
1699 if (const auto *SHT = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) {
1700 if (SHT->NoHeaders && (SHT->Sections || SHT->Excluded || SHT->Offset))
1701 return "NoHeaders can't be used together with Offset/Sections/Excluded";
1702 return "";
1703 }
1704
1705 const ELFYAML::Section &Sec = *cast<ELFYAML::Section>(C.get());
1706 if (Sec.Size && Sec.Content &&
1707 (uint64_t)(*Sec.Size) < Sec.Content->binary_size())
1708 return "Section size must be greater than or equal to the content size";
1709
1710 auto BuildErrPrefix = [](ArrayRef<std::pair<StringRef, bool>> EntV) {
1711 std::string Msg;
1712 for (size_t I = 0, E = EntV.size(); I != E; ++I) {
1713 StringRef Name = EntV[I].first;
1714 if (I == 0) {
1715 Msg = "\"" + Name.str() + "\"";
1716 continue;
1717 }
1718 if (I != EntV.size() - 1)
1719 Msg += ", \"" + Name.str() + "\"";
1720 else
1721 Msg += " and \"" + Name.str() + "\"";
1722 }
1723 return Msg;
1724 };
1725
1726 std::vector<std::pair<StringRef, bool>> Entries = Sec.getEntries();
1727 const size_t NumUsedEntries = llvm::count_if(
1728 Entries, [](const std::pair<StringRef, bool> &P) { return P.second; });
1729
1730 if ((Sec.Size || Sec.Content) && NumUsedEntries > 0)
1731 return BuildErrPrefix(Entries) +
1732 " cannot be used with \"Content\" or \"Size\"";
1733
1734 if (NumUsedEntries > 0 && Entries.size() != NumUsedEntries)
1735 return BuildErrPrefix(Entries) + " must be used together";
1736
1737 if (const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(C.get())) {
1738 if (RawSection->Flags && RawSection->ShFlags)
1739 return "ShFlags and Flags cannot be used together";
1740 return "";
1741 }
1742
1743 if (const auto *NB = dyn_cast<ELFYAML::NoBitsSection>(C.get())) {
1744 if (NB->Content)
1745 return "SHT_NOBITS section cannot have \"Content\"";
1746 return "";
1747 }
1748
1749 if (const auto *MF = dyn_cast<ELFYAML::MipsABIFlags>(C.get())) {
1750 if (MF->Content)
1751 return "\"Content\" key is not implemented for SHT_MIPS_ABIFLAGS "
1752 "sections";
1753 if (MF->Size)
1754 return "\"Size\" key is not implemented for SHT_MIPS_ABIFLAGS sections";
1755 return "";
1756 }
1757
1758 return "";
1759}
1760
1761namespace {
1762
1763struct NormalizedMips64RelType {
1764 NormalizedMips64RelType(IO &)
1765 : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1766 Type2(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1767 Type3(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1768 SpecSym(ELFYAML::ELF_REL(ELF::RSS_UNDEF)) {}
1769 NormalizedMips64RelType(IO &, ELFYAML::ELF_REL Original)
1770 : Type(Original & 0xFF), Type2(Original >> 8 & 0xFF),
1771 Type3(Original >> 16 & 0xFF), SpecSym(Original >> 24 & 0xFF) {}
1772
1773 ELFYAML::ELF_REL denormalize(IO &) {
1774 ELFYAML::ELF_REL Res = Type | Type2 << 8 | Type3 << 16 | SpecSym << 24;
1775 return Res;
1776 }
1777
1778 ELFYAML::ELF_REL Type;
1779 ELFYAML::ELF_REL Type2;
1780 ELFYAML::ELF_REL Type3;
1781 ELFYAML::ELF_RSS SpecSym;
1782};
1783
1784} // end anonymous namespace
1785
1786void MappingTraits<ELFYAML::StackSizeEntry>::mapping(
1787 IO &IO, ELFYAML::StackSizeEntry &E) {
1788 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", 1788, __extension__ __PRETTY_FUNCTION__
))
;
1789 IO.mapOptional("Address", E.Address, Hex64(0));
1790 IO.mapRequired("Size", E.Size);
1791}
1792
1793void MappingTraits<ELFYAML::BBAddrMapEntry>::mapping(
1794 IO &IO, ELFYAML::BBAddrMapEntry &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.mapRequired("Version", E.Version);
1797 IO.mapOptional("Feature", E.Feature, Hex8(0));
1798 IO.mapOptional("Address", E.Address, Hex64(0));
1799 IO.mapOptional("NumBlocks", E.NumBlocks);
1800 IO.mapOptional("BBEntries", E.BBEntries);
1801}
1802
1803void MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry>::mapping(
1804 IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E) {
1805 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", 1805, __extension__ __PRETTY_FUNCTION__
))
;
1806 IO.mapOptional("ID", E.ID);
1807 IO.mapRequired("AddressOffset", E.AddressOffset);
1808 IO.mapRequired("Size", E.Size);
1809 IO.mapRequired("Metadata", E.Metadata);
1810}
1811
1812void MappingTraits<ELFYAML::GnuHashHeader>::mapping(IO &IO,
1813 ELFYAML::GnuHashHeader &E) {
1814 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", 1814, __extension__ __PRETTY_FUNCTION__
))
;
1815 IO.mapOptional("NBuckets", E.NBuckets);
1816 IO.mapRequired("SymNdx", E.SymNdx);
1817 IO.mapOptional("MaskWords", E.MaskWords);
1818 IO.mapRequired("Shift2", E.Shift2);
1819}
1820
1821void MappingTraits<ELFYAML::DynamicEntry>::mapping(IO &IO,
1822 ELFYAML::DynamicEntry &Rel) {
1823 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", 1823, __extension__ __PRETTY_FUNCTION__
))
;
1824
1825 IO.mapRequired("Tag", Rel.Tag);
1826 IO.mapRequired("Value", Rel.Val);
1827}
1828
1829void MappingTraits<ELFYAML::NoteEntry>::mapping(IO &IO, ELFYAML::NoteEntry &N) {
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.mapOptional("Name", N.Name);
1833 IO.mapOptional("Desc", N.Desc);
1834 IO.mapRequired("Type", N.Type);
1835}
1836
1837void MappingTraits<ELFYAML::VerdefEntry>::mapping(IO &IO,
1838 ELFYAML::VerdefEntry &E) {
1839 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", 1839, __extension__ __PRETTY_FUNCTION__
))
;
1840
1841 IO.mapOptional("Version", E.Version);
1842 IO.mapOptional("Flags", E.Flags);
1843 IO.mapOptional("VersionNdx", E.VersionNdx);
1844 IO.mapOptional("Hash", E.Hash);
1845 IO.mapRequired("Names", E.VerNames);
1846}
1847
1848void MappingTraits<ELFYAML::VerneedEntry>::mapping(IO &IO,
1849 ELFYAML::VerneedEntry &E) {
1850 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", 1850, __extension__ __PRETTY_FUNCTION__
))
;
1851
1852 IO.mapRequired("Version", E.Version);
1853 IO.mapRequired("File", E.File);
1854 IO.mapRequired("Entries", E.AuxV);
1855}
1856
1857void MappingTraits<ELFYAML::VernauxEntry>::mapping(IO &IO,
1858 ELFYAML::VernauxEntry &E) {
1859 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", 1859, __extension__ __PRETTY_FUNCTION__
))
;
1860
1861 IO.mapRequired("Name", E.Name);
1862 IO.mapRequired("Hash", E.Hash);
1863 IO.mapRequired("Flags", E.Flags);
1864 IO.mapRequired("Other", E.Other);
1865}
1866
1867void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
1868 ELFYAML::Relocation &Rel) {
1869 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
1870 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", 1870, __extension__ __PRETTY_FUNCTION__
))
;
1871
1872 IO.mapOptional("Offset", Rel.Offset, (Hex64)0);
1873 IO.mapOptional("Symbol", Rel.Symbol);
1874
1875 if (Object->getMachine() == ELFYAML::ELF_EM(ELF::EM_MIPS) &&
1876 Object->Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64)) {
1877 MappingNormalization<NormalizedMips64RelType, ELFYAML::ELF_REL> Key(
1878 IO, Rel.Type);
1879 IO.mapRequired("Type", Key->Type);
1880 IO.mapOptional("Type2", Key->Type2, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
1881 IO.mapOptional("Type3", Key->Type3, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
1882 IO.mapOptional("SpecSym", Key->SpecSym, ELFYAML::ELF_RSS(ELF::RSS_UNDEF));
1883 } else
1884 IO.mapRequired("Type", Rel.Type);
1885
1886 IO.mapOptional("Addend", Rel.Addend, (ELFYAML::YAMLIntUInt)0);
1887}
1888
1889void MappingTraits<ELFYAML::ARMIndexTableEntry>::mapping(
1890 IO &IO, ELFYAML::ARMIndexTableEntry &E) {
1891 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", 1891, __extension__ __PRETTY_FUNCTION__
))
;
1892 IO.mapRequired("Offset", E.Offset);
1893
1894 StringRef CantUnwind = "EXIDX_CANTUNWIND";
1895 if (IO.outputting() && (uint32_t)E.Value == ARM::EHABI::EXIDX_CANTUNWIND)
1896 IO.mapRequired("Value", CantUnwind);
1897 else if (!IO.outputting() && getStringValue(IO, "Value") == CantUnwind)
1898 E.Value = ARM::EHABI::EXIDX_CANTUNWIND;
1899 else
1900 IO.mapRequired("Value", E.Value);
1901}
1902
1903void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
1904 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", 1904, __extension__ __PRETTY_FUNCTION__
))
;
1905 IO.setContext(&Object);
1906 IO.mapTag("!ELF", true);
1907 IO.mapRequired("FileHeader", Object.Header);
1908 IO.mapOptional("ProgramHeaders", Object.ProgramHeaders);
1909 IO.mapOptional("Sections", Object.Chunks);
1910 IO.mapOptional("Symbols", Object.Symbols);
1911 IO.mapOptional("DynamicSymbols", Object.DynamicSymbols);
1912 IO.mapOptional("DWARF", Object.DWARF);
1913 if (Object.DWARF) {
1914 Object.DWARF->IsLittleEndian =
1915 Object.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
1916 Object.DWARF->Is64BitAddrSize =
1917 Object.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
1918 }
1919 IO.setContext(nullptr);
1920}
1921
1922void MappingTraits<ELFYAML::LinkerOption>::mapping(IO &IO,
1923 ELFYAML::LinkerOption &Opt) {
1924 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", 1924, __extension__ __PRETTY_FUNCTION__
))
;
1925 IO.mapRequired("Name", Opt.Key);
1926 IO.mapRequired("Value", Opt.Value);
1927}
1928
1929void MappingTraits<ELFYAML::CallGraphEntryWeight>::mapping(
1930 IO &IO, ELFYAML::CallGraphEntryWeight &E) {
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("Weight", E.Weight);
1933}
1934
1935LLVM_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; }
;
1936LLVM_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; }
;
1937LLVM_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;
};
1938LLVM_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;
};
1939LLVM_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;
};
1940
1941} // end namespace yaml
1942
1943} // 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'
21
The left operand of '==' is a garbage 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<T>::value>
510class has_FlowTraits
511{
512public:
513 static const bool value = false;
514};
515
516// Some older gcc compilers don't support straight forward tests
517// for members, so test for ambiguity cause by the base and derived
518// classes both defining the member.
519template <class T>
520struct has_FlowTraits<T, true>
521{
522 struct Fallback { bool flow; };
523 struct Derived : T, Fallback { };
524
525 template<typename C>
526 static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
527
528 template<typename C>
529 static char (&f(...))[2];
530
531 static bool const value = sizeof(f<Derived>(nullptr)) == 2;
532};
533
534// Test if SequenceTraits<T> is defined on type T
535template<typename T>
536struct has_SequenceTraits : public std::integral_constant<bool,
537 has_SequenceMethodTraits<T>::value > { };
538
539// Test if DocumentListTraits<T> is defined on type T
540template <class T>
541struct has_DocumentListTraits
542{
543 using Signature_size = size_t (*)(class IO &, T &);
544
545 template <typename U>
546 static char test(SameType<Signature_size, &U::size>*);
547
548 template <typename U>
549 static double test(...);
550
551 static bool const value = (sizeof(test<DocumentListTraits<T>>(nullptr))==1);
552};
553
554template <class T> struct has_PolymorphicTraits {
555 using Signature_getKind = NodeKind (*)(const T &);
556
557 template <typename U>
558 static char test(SameType<Signature_getKind, &U::getKind> *);
559
560 template <typename U> static double test(...);
561
562 static bool const value = (sizeof(test<PolymorphicTraits<T>>(nullptr)) == 1);
563};
564
565inline bool isNumeric(StringRef S) {
566 const auto skipDigits = [](StringRef Input) {
567 return Input.ltrim("0123456789");
568 };
569
570 // Make S.front() and S.drop_front().front() (if S.front() is [+-]) calls
571 // safe.
572 if (S.empty() || S.equals("+") || S.equals("-"))
573 return false;
574
575 if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
576 return true;
577
578 // Infinity and decimal numbers can be prefixed with sign.
579 StringRef Tail = (S.front() == '-' || S.front() == '+') ? S.drop_front() : S;
580
581 // Check for infinity first, because checking for hex and oct numbers is more
582 // expensive.
583 if (Tail.equals(".inf") || Tail.equals(".Inf") || Tail.equals(".INF"))
584 return true;
585
586 // Section 10.3.2 Tag Resolution
587 // YAML 1.2 Specification prohibits Base 8 and Base 16 numbers prefixed with
588 // [-+], so S should be used instead of Tail.
589 if (S.startswith("0o"))
590 return S.size() > 2 &&
591 S.drop_front(2).find_first_not_of("01234567") == StringRef::npos;
592
593 if (S.startswith("0x"))
594 return S.size() > 2 && S.drop_front(2).find_first_not_of(
595 "0123456789abcdefABCDEF") == StringRef::npos;
596
597 // Parse float: [-+]? (\. [0-9]+ | [0-9]+ (\. [0-9]* )?) ([eE] [-+]? [0-9]+)?
598 S = Tail;
599
600 // Handle cases when the number starts with '.' and hence needs at least one
601 // digit after dot (as opposed by number which has digits before the dot), but
602 // doesn't have one.
603 if (S.startswith(".") &&
604 (S.equals(".") ||
605 (S.size() > 1 && std::strchr("0123456789", S[1]) == nullptr)))
606 return false;
607
608 if (S.startswith("E") || S.startswith("e"))
609 return false;
610
611 enum ParseState {
612 Default,
613 FoundDot,
614 FoundExponent,
615 };
616 ParseState State = Default;
617
618 S = skipDigits(S);
619
620 // Accept decimal integer.
621 if (S.empty())
622 return true;
623
624 if (S.front() == '.') {
625 State = FoundDot;
626 S = S.drop_front();
627 } else if (S.front() == 'e' || S.front() == 'E') {
628 State = FoundExponent;
629 S = S.drop_front();
630 } else {
631 return false;
632 }
633
634 if (State == FoundDot) {
635 S = skipDigits(S);
636 if (S.empty())
637 return true;
638
639 if (S.front() == 'e' || S.front() == 'E') {
640 State = FoundExponent;
641 S = S.drop_front();
642 } else {
643 return false;
644 }
645 }
646
647 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", 647, __extension__
__PRETTY_FUNCTION__))
;
648 if (S.empty())
649 return false;
650
651 if (S.front() == '+' || S.front() == '-') {
652 S = S.drop_front();
653 if (S.empty())
654 return false;
655 }
656
657 return skipDigits(S).empty();
658}
659
660inline bool isNull(StringRef S) {
661 return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
662 S.equals("~");
663}
664
665inline bool isBool(StringRef S) {
666 // FIXME: using parseBool is causing multiple tests to fail.
667 return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
668 S.equals("false") || S.equals("False") || S.equals("FALSE");
669}
670
671// 5.1. Character Set
672// The allowed character range explicitly excludes the C0 control block #x0-#x1F
673// (except for TAB #x9, LF #xA, and CR #xD which are allowed), DEL #x7F, the C1
674// control block #x80-#x9F (except for NEL #x85 which is allowed), the surrogate
675// block #xD800-#xDFFF, #xFFFE, and #xFFFF.
676inline QuotingType needsQuotes(StringRef S) {
677 if (S.empty())
678 return QuotingType::Single;
679
680 QuotingType MaxQuotingNeeded = QuotingType::None;
681 if (isSpace(static_cast<unsigned char>(S.front())) ||
682 isSpace(static_cast<unsigned char>(S.back())))
683 MaxQuotingNeeded = QuotingType::Single;
684 if (isNull(S))
685 MaxQuotingNeeded = QuotingType::Single;
686 if (isBool(S))
687 MaxQuotingNeeded = QuotingType::Single;
688 if (isNumeric(S))
689 MaxQuotingNeeded = QuotingType::Single;
690
691 // 7.3.3 Plain Style
692 // Plain scalars must not begin with most indicators, as this would cause
693 // ambiguity with other YAML constructs.
694 if (std::strchr(R"(-?:\,[]{}#&*!|>'"%@`)", S[0]) != nullptr)
695 MaxQuotingNeeded = QuotingType::Single;
696
697 for (unsigned char C : S) {
698 // Alphanum is safe.
699 if (isAlnum(C))
700 continue;
701
702 switch (C) {
703 // Safe scalar characters.
704 case '_':
705 case '-':
706 case '^':
707 case '.':
708 case ',':
709 case ' ':
710 // TAB (0x9) is allowed in unquoted strings.
711 case 0x9:
712 continue;
713 // LF(0xA) and CR(0xD) may delimit values and so require at least single
714 // quotes. LLVM YAML parser cannot handle single quoted multiline so use
715 // double quoting to produce valid YAML.
716 case 0xA:
717 case 0xD:
718 return QuotingType::Double;
719 // DEL (0x7F) are excluded from the allowed character range.
720 case 0x7F:
721 return QuotingType::Double;
722 // Forward slash is allowed to be unquoted, but we quote it anyway. We have
723 // many tests that use FileCheck against YAML output, and this output often
724 // contains paths. If we quote backslashes but not forward slashes then
725 // paths will come out either quoted or unquoted depending on which platform
726 // the test is run on, making FileCheck comparisons difficult.
727 case '/':
728 default: {
729 // C0 control block (0x0 - 0x1F) is excluded from the allowed character
730 // range.
731 if (C <= 0x1F)
732 return QuotingType::Double;
733
734 // Always double quote UTF-8.
735 if ((C & 0x80) != 0)
736 return QuotingType::Double;
737
738 // The character is not safe, at least simple quoting needed.
739 MaxQuotingNeeded = QuotingType::Single;
740 }
741 }
742 }
743
744 return MaxQuotingNeeded;
745}
746
747template <typename T, typename Context>
748struct missingTraits
749 : public std::integral_constant<bool,
750 !has_ScalarEnumerationTraits<T>::value &&
751 !has_ScalarBitSetTraits<T>::value &&
752 !has_ScalarTraits<T>::value &&
753 !has_BlockScalarTraits<T>::value &&
754 !has_TaggedScalarTraits<T>::value &&
755 !has_MappingTraits<T, Context>::value &&
756 !has_SequenceTraits<T>::value &&
757 !has_CustomMappingTraits<T>::value &&
758 !has_DocumentListTraits<T>::value &&
759 !has_PolymorphicTraits<T>::value> {};
760
761template <typename T, typename Context>
762struct validatedMappingTraits
763 : public std::integral_constant<
764 bool, has_MappingTraits<T, Context>::value &&
765 has_MappingValidateTraits<T, Context>::value> {};
766
767template <typename T, typename Context>
768struct unvalidatedMappingTraits
769 : public std::integral_constant<
770 bool, has_MappingTraits<T, Context>::value &&
771 !has_MappingValidateTraits<T, Context>::value> {};
772
773// Base class for Input and Output.
774class IO {
775public:
776 IO(void *Ctxt = nullptr);
777 virtual ~IO();
778
779 virtual bool outputting() const = 0;
780
781 virtual unsigned beginSequence() = 0;
782 virtual bool preflightElement(unsigned, void *&) = 0;
783 virtual void postflightElement(void*) = 0;
784 virtual void endSequence() = 0;
785 virtual bool canElideEmptySequence() = 0;
786
787 virtual unsigned beginFlowSequence() = 0;
788 virtual bool preflightFlowElement(unsigned, void *&) = 0;
789 virtual void postflightFlowElement(void*) = 0;
790 virtual void endFlowSequence() = 0;
791
792 virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
793 virtual void beginMapping() = 0;
794 virtual void endMapping() = 0;
795 virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
796 virtual void postflightKey(void*) = 0;
797 virtual std::vector<StringRef> keys() = 0;
798
799 virtual void beginFlowMapping() = 0;
800 virtual void endFlowMapping() = 0;
801
802 virtual void beginEnumScalar() = 0;
803 virtual bool matchEnumScalar(const char*, bool) = 0;
804 virtual bool matchEnumFallback() = 0;
805 virtual void endEnumScalar() = 0;
806
807 virtual bool beginBitSetScalar(bool &) = 0;
808 virtual bool bitSetMatch(const char*, bool) = 0;
809 virtual void endBitSetScalar() = 0;
810
811 virtual void scalarString(StringRef &, QuotingType) = 0;
812 virtual void blockScalarString(StringRef &) = 0;
813 virtual void scalarTag(std::string &) = 0;
814
815 virtual NodeKind getNodeKind() = 0;
816
817 virtual void setError(const Twine &) = 0;
818 virtual void setAllowUnknownKeys(bool Allow);
819
820 template <typename T>
821 void enumCase(T &Val, const char* Str, const T ConstVal) {
822 if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
823 Val = ConstVal;
824 }
825 }
826
827 // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
828 template <typename T>
829 void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
830 if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
831 Val = ConstVal;
832 }
833 }
834
835 template <typename FBT, typename T>
836 void enumFallback(T &Val) {
837 if (matchEnumFallback()) {
838 EmptyContext Context;
839 // FIXME: Force integral conversion to allow strong typedefs to convert.
840 FBT Res = static_cast<typename FBT::BaseType>(Val);
841 yamlize(*this, Res, true, Context);
842 Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
843 }
844 }
845
846 template <typename T>
847 void bitSetCase(T &Val, const char* Str, const T ConstVal) {
848 if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
849 Val = static_cast<T>(Val | ConstVal);
850 }
851 }
852
853 // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
854 template <typename T>
855 void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
856 if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
857 Val = static_cast<T>(Val | ConstVal);
858 }
859 }
860
861 template <typename T>
862 void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
863 if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
864 Val = Val | ConstVal;
865 }
866
867 template <typename T>
868 void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
869 uint32_t Mask) {
870 if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
871 Val = Val | ConstVal;
872 }
873
874 void *getContext() const;
875 void setContext(void *);
876
877 template <typename T> void mapRequired(const char *Key, T &Val) {
878 EmptyContext Ctx;
879 this->processKey(Key, Val, true, Ctx);
8
Calling 'IO::processKey'
12
Returning from 'IO::processKey'
880 }
13
Returning without writing to 'Val.value'
881
882 template <typename T, typename Context>
883 void mapRequired(const char *Key, T &Val, Context &Ctx) {
884 this->processKey(Key, Val, true, Ctx);
885 }
886
887 template <typename T> void mapOptional(const char *Key, T &Val) {
888 EmptyContext Ctx;
889 mapOptionalWithContext(Key, Val, Ctx);
890 }
891
892 template <typename T, typename DefaultT>
893 void mapOptional(const char *Key, T &Val, const DefaultT &Default) {
894 EmptyContext Ctx;
895 mapOptionalWithContext(Key, Val, Default, Ctx);
896 }
897
898 template <typename T, typename Context>
899 std::enable_if_t<has_SequenceTraits<T>::value, void>
900 mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
901 // omit key/value instead of outputting empty sequence
902 if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
903 return;
904 this->processKey(Key, Val, false, Ctx);
905 }
906
907 template <typename T, typename Context>
908 void mapOptionalWithContext(const char *Key, std::optional<T> &Val,
909 Context &Ctx) {
910 this->processKeyWithDefault(Key, Val, std::optional<T>(),
911 /*Required=*/false, Ctx);
912 }
913
914 template <typename T, typename Context>
915 std::enable_if_t<!has_SequenceTraits<T>::value, void>
916 mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
917 this->processKey(Key, Val, false, Ctx);
918 }
919
920 template <typename T, typename Context, typename DefaultT>
921 void mapOptionalWithContext(const char *Key, T &Val, const DefaultT &Default,
922 Context &Ctx) {
923 static_assert(std::is_convertible<DefaultT, T>::value,
924 "Default type must be implicitly convertible to value type!");
925 this->processKeyWithDefault(Key, Val, static_cast<const T &>(Default),
926 false, Ctx);
927 }
928
929private:
930 template <typename T, typename Context>
931 void processKeyWithDefault(const char *Key, std::optional<T> &Val,
932 const std::optional<T> &DefaultValue,
933 bool Required, Context &Ctx);
934
935 template <typename T, typename Context>
936 void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
937 bool Required, Context &Ctx) {
938 void *SaveInfo;
939 bool UseDefault;
940 const bool sameAsDefault = outputting() && Val == DefaultValue;
941 if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
942 SaveInfo) ) {
943 yamlize(*this, Val, Required, Ctx);
944 this->postflightKey(SaveInfo);
945 }
946 else {
947 if ( UseDefault )
948 Val = DefaultValue;
949 }
950 }
951
952 template <typename T, typename Context>
953 void processKey(const char *Key, T &Val, bool Required, Context &Ctx) {
954 void *SaveInfo;
955 bool UseDefault;
956 if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
9
Assuming the condition is false
10
Taking false branch
957 yamlize(*this, Val, Required, Ctx);
958 this->postflightKey(SaveInfo);
959 }
960 }
11
Returning without writing to 'Val.value'
961
962private:
963 void *Ctxt;
964};
965
966namespace detail {
967
968template <typename T, typename Context>
969void doMapping(IO &io, T &Val, Context &Ctx) {
970 MappingContextTraits<T, Context>::mapping(io, Val, Ctx);
971}
972
973template <typename T> void doMapping(IO &io, T &Val, EmptyContext &Ctx) {
974 MappingTraits<T>::mapping(io, Val);
975}
976
977} // end namespace detail
978
979template <typename T>
980std::enable_if_t<has_ScalarEnumerationTraits<T>::value, void>
981yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
982 io.beginEnumScalar();
983 ScalarEnumerationTraits<T>::enumeration(io, Val);
984 io.endEnumScalar();
985}
986
987template <typename T>
988std::enable_if_t<has_ScalarBitSetTraits<T>::value, void>
989yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
990 bool DoClear;
991 if ( io.beginBitSetScalar(DoClear) ) {
992 if ( DoClear )
993 Val = T();
994 ScalarBitSetTraits<T>::bitset(io, Val);
995 io.endBitSetScalar();
996 }
997}
998
999template <typename T>
1000std::enable_if_t<has_ScalarTraits<T>::value, void> yamlize(IO &io, T &Val, bool,
1001 EmptyContext &Ctx) {
1002 if ( io.outputting() ) {
1003 SmallString<128> Storage;
1004 raw_svector_ostream Buffer(Storage);
1005 ScalarTraits<T>::output(Val, io.getContext(), Buffer);
1006 StringRef Str = Buffer.str();
1007 io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
1008 }
1009 else {
1010 StringRef Str;
1011 io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
1012 StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
1013 if ( !Result.empty() ) {
1014 io.setError(Twine(Result));
1015 }
1016 }
1017}
1018
1019template <typename T>
1020std::enable_if_t<has_BlockScalarTraits<T>::value, void>
1021yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
1022 if (YamlIO.outputting()) {
1023 std::string Storage;
1024 raw_string_ostream Buffer(Storage);
1025 BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
1026 StringRef Str = Buffer.str();
1027 YamlIO.blockScalarString(Str);
1028 } else {
1029 StringRef Str;
1030 YamlIO.blockScalarString(Str);
1031 StringRef Result =
1032 BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
1033 if (!Result.empty())
1034 YamlIO.setError(Twine(Result));
1035 }
1036}
1037
1038template <typename T>
1039std::enable_if_t<has_TaggedScalarTraits<T>::value, void>
1040yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1041 if (io.outputting()) {
1042 std::string ScalarStorage, TagStorage;
1043 raw_string_ostream ScalarBuffer(ScalarStorage), TagBuffer(TagStorage);
1044 TaggedScalarTraits<T>::output(Val, io.getContext(), ScalarBuffer,
1045 TagBuffer);
1046 io.scalarTag(TagBuffer.str());
1047 StringRef ScalarStr = ScalarBuffer.str();
1048 io.scalarString(ScalarStr,
1049 TaggedScalarTraits<T>::mustQuote(Val, ScalarStr));
1050 } else {
1051 std::string Tag;
1052 io.scalarTag(Tag);
1053 StringRef Str;
1054 io.scalarString(Str, QuotingType::None);
1055 StringRef Result =
1056 TaggedScalarTraits<T>::input(Str, Tag, io.getContext(), Val);
1057 if (!Result.empty()) {
1058 io.setError(Twine(Result));
1059 }
1060 }
1061}
1062
1063template <typename T, typename Context>
1064std::enable_if_t<validatedMappingTraits<T, Context>::value, void>
1065yamlize(IO &io, T &Val, bool, Context &Ctx) {
1066 if (has_FlowTraits<MappingTraits<T>>::value)
1067 io.beginFlowMapping();
1068 else
1069 io.beginMapping();
1070 if (io.outputting()) {
1071 std::string Err = MappingTraits<T>::validate(io, Val);
1072 if (!Err.empty()) {
1073 errs() << Err << "\n";
1074 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", 1074, __extension__
__PRETTY_FUNCTION__))
;
1075 }
1076 }
1077 detail::doMapping(io, Val, Ctx);
1078 if (!io.outputting()) {
1079 std::string Err = MappingTraits<T>::validate(io, Val);
1080 if (!Err.empty())
1081 io.setError(Err);
1082 }
1083 if (has_FlowTraits<MappingTraits<T>>::value)
1084 io.endFlowMapping();
1085 else
1086 io.endMapping();
1087}
1088
1089template <typename T, typename Context>
1090std::enable_if_t<!has_MappingEnumInputTraits<T, Context>::value, bool>
1091yamlizeMappingEnumInput(IO &io, T &Val) {
1092 return false;
1093}
1094
1095template <typename T, typename Context>
1096std::enable_if_t<has_MappingEnumInputTraits<T, Context>::value, bool>
1097yamlizeMappingEnumInput(IO &io, T &Val) {
1098 if (io.outputting())
1099 return false;
1100
1101 io.beginEnumScalar();
1102 MappingTraits<T>::enumInput(io, Val);
1103 bool Matched = !io.matchEnumFallback();
1104 io.endEnumScalar();
1105 return Matched;
1106}
1107
1108template <typename T, typename Context>
1109std::enable_if_t<unvalidatedMappingTraits<T, Context>::value, void>
1110yamlize(IO &io, T &Val, bool, Context &Ctx) {
1111 if (yamlizeMappingEnumInput<T, Context>(io, Val))
1112 return;
1113 if (has_FlowTraits<MappingTraits<T>>::value) {
1114 io.beginFlowMapping();
1115 detail::doMapping(io, Val, Ctx);
1116 io.endFlowMapping();
1117 } else {
1118 io.beginMapping();
1119 detail::doMapping(io, Val, Ctx);
1120 io.endMapping();
1121 }
1122}
1123
1124template <typename T>
1125std::enable_if_t<has_CustomMappingTraits<T>::value, void>
1126yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1127 if ( io.outputting() ) {
1128 io.beginMapping();
1129 CustomMappingTraits<T>::output(io, Val);
1130 io.endMapping();
1131 } else {
1132 io.beginMapping();
1133 for (StringRef key : io.keys())
1134 CustomMappingTraits<T>::inputOne(io, key, Val);
1135 io.endMapping();
1136 }
1137}
1138
1139template <typename T>
1140std::enable_if_t<has_PolymorphicTraits<T>::value, void>
1141yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1142 switch (io.outputting() ? PolymorphicTraits<T>::getKind(Val)
1143 : io.getNodeKind()) {
1144 case NodeKind::Scalar:
1145 return yamlize(io, PolymorphicTraits<T>::getAsScalar(Val), true, Ctx);
1146 case NodeKind::Map:
1147 return yamlize(io, PolymorphicTraits<T>::getAsMap(Val), true, Ctx);
1148 case NodeKind::Sequence:
1149 return yamlize(io, PolymorphicTraits<T>::getAsSequence(Val), true, Ctx);
1150 }
1151}
1152
1153template <typename T>
1154std::enable_if_t<missingTraits<T, EmptyContext>::value, void>
1155yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1156 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1157}
1158
1159template <typename T, typename Context>
1160std::enable_if_t<has_SequenceTraits<T>::value, void>
1161yamlize(IO &io, T &Seq, bool, Context &Ctx) {
1162 if ( has_FlowTraits< SequenceTraits<T>>::value ) {
1163 unsigned incnt = io.beginFlowSequence();
1164 unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1165 for(unsigned i=0; i < count; ++i) {
1166 void *SaveInfo;
1167 if ( io.preflightFlowElement(i, SaveInfo) ) {
1168 yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1169 io.postflightFlowElement(SaveInfo);
1170 }
1171 }
1172 io.endFlowSequence();
1173 }
1174 else {
1175 unsigned incnt = io.beginSequence();
1176 unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1177 for(unsigned i=0; i < count; ++i) {
1178 void *SaveInfo;
1179 if ( io.preflightElement(i, SaveInfo) ) {
1180 yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1181 io.postflightElement(SaveInfo);
1182 }
1183 }
1184 io.endSequence();
1185 }
1186}
1187
1188template<>
1189struct ScalarTraits<bool> {
1190 static void output(const bool &, void* , raw_ostream &);
1191 static StringRef input(StringRef, void *, bool &);
1192 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1193};
1194
1195template<>
1196struct ScalarTraits<StringRef> {
1197 static void output(const StringRef &, void *, raw_ostream &);
1198 static StringRef input(StringRef, void *, StringRef &);
1199 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1200};
1201
1202template<>
1203struct ScalarTraits<std::string> {
1204 static void output(const std::string &, void *, raw_ostream &);
1205 static StringRef input(StringRef, void *, std::string &);
1206 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1207};
1208
1209template<>
1210struct ScalarTraits<uint8_t> {
1211 static void output(const uint8_t &, void *, raw_ostream &);
1212 static StringRef input(StringRef, void *, uint8_t &);
1213 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1214};
1215
1216template<>
1217struct ScalarTraits<uint16_t> {
1218 static void output(const uint16_t &, void *, raw_ostream &);
1219 static StringRef input(StringRef, void *, uint16_t &);
1220 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1221};
1222
1223template<>
1224struct ScalarTraits<uint32_t> {
1225 static void output(const uint32_t &, void *, raw_ostream &);
1226 static StringRef input(StringRef, void *, uint32_t &);
1227 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1228};
1229
1230template<>
1231struct ScalarTraits<uint64_t> {
1232 static void output(const uint64_t &, void *, raw_ostream &);
1233 static StringRef input(StringRef, void *, uint64_t &);
1234 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1235};
1236
1237template<>
1238struct ScalarTraits<int8_t> {
1239 static void output(const int8_t &, void *, raw_ostream &);
1240 static StringRef input(StringRef, void *, int8_t &);
1241 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1242};
1243
1244template<>
1245struct ScalarTraits<int16_t> {
1246 static void output(const int16_t &, void *, raw_ostream &);
1247 static StringRef input(StringRef, void *, int16_t &);
1248 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1249};
1250
1251template<>
1252struct ScalarTraits<int32_t> {
1253 static void output(const int32_t &, void *, raw_ostream &);
1254 static StringRef input(StringRef, void *, int32_t &);
1255 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1256};
1257
1258template<>
1259struct ScalarTraits<int64_t> {
1260 static void output(const int64_t &, void *, raw_ostream &);
1261 static StringRef input(StringRef, void *, int64_t &);
1262 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1263};
1264
1265template<>
1266struct ScalarTraits<float> {
1267 static void output(const float &, void *, raw_ostream &);
1268 static StringRef input(StringRef, void *, float &);
1269 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1270};
1271
1272template<>
1273struct ScalarTraits<double> {
1274 static void output(const double &, void *, raw_ostream &);
1275 static StringRef input(StringRef, void *, double &);
1276 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1277};
1278
1279// For endian types, we use existing scalar Traits class for the underlying
1280// type. This way endian aware types are supported whenever the traits are
1281// defined for the underlying type.
1282template <typename value_type, support::endianness endian, size_t alignment>
1283struct ScalarTraits<support::detail::packed_endian_specific_integral<
1284 value_type, endian, alignment>,
1285 std::enable_if_t<has_ScalarTraits<value_type>::value>> {
1286 using endian_type =
1287 support::detail::packed_endian_specific_integral<value_type, endian,
1288 alignment>;
1289
1290 static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) {
1291 ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
1292 }
1293
1294 static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
1295 value_type V;
1296 auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
1297 E = static_cast<endian_type>(V);
1298 return R;
1299 }
1300
1301 static QuotingType mustQuote(StringRef Str) {
1302 return ScalarTraits<value_type>::mustQuote(Str);
1303 }
1304};
1305
1306template <typename value_type, support::endianness endian, size_t alignment>
1307struct ScalarEnumerationTraits<
1308 support::detail::packed_endian_specific_integral<value_type, endian,
1309 alignment>,
1310 std::enable_if_t<has_ScalarEnumerationTraits<value_type>::value>> {
1311 using endian_type =
1312 support::detail::packed_endian_specific_integral<value_type, endian,
1313 alignment>;
1314
1315 static void enumeration(IO &io, endian_type &E) {
1316 value_type V = E;
1317 ScalarEnumerationTraits<value_type>::enumeration(io, V);
1318 E = V;
1319 }
1320};
1321
1322template <typename value_type, support::endianness endian, size_t alignment>
1323struct ScalarBitSetTraits<
1324 support::detail::packed_endian_specific_integral<value_type, endian,
1325 alignment>,
1326 std::enable_if_t<has_ScalarBitSetTraits<value_type>::value>> {
1327 using endian_type =
1328 support::detail::packed_endian_specific_integral<value_type, endian,
1329 alignment>;
1330 static void bitset(IO &io, endian_type &E) {
1331 value_type V = E;
1332 ScalarBitSetTraits<value_type>::bitset(io, V);
1333 E = V;
1334 }
1335};
1336
1337// Utility for use within MappingTraits<>::mapping() method
1338// to [de]normalize an object for use with YAML conversion.
1339template <typename TNorm, typename TFinal>
1340struct MappingNormalization {
1341 MappingNormalization(IO &i_o, TFinal &Obj)
1342 : io(i_o), BufPtr(nullptr), Result(Obj) {
1343 if ( io.outputting() ) {
1344 BufPtr = new (&Buffer) TNorm(io, Obj);
1345 }
1346 else {
1347 BufPtr = new (&Buffer) TNorm(io);
1348 }
1349 }
1350
1351 ~MappingNormalization() {
1352 if ( ! io.outputting() ) {
1353 Result = BufPtr->denormalize(io);
1354 }
1355 BufPtr->~TNorm();
1356 }
1357
1358 TNorm* operator->() { return BufPtr; }
1359
1360private:
1361 using Storage = AlignedCharArrayUnion<TNorm>;
1362
1363 Storage Buffer;
1364 IO &io;
1365 TNorm *BufPtr;
1366 TFinal &Result;
1367};
1368
1369// Utility for use within MappingTraits<>::mapping() method
1370// to [de]normalize an object for use with YAML conversion.
1371template <typename TNorm, typename TFinal>
1372struct MappingNormalizationHeap {
1373 MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator)
1374 : io(i_o), Result(Obj) {
1375 if ( io.outputting() ) {
1376 BufPtr = new (&Buffer) TNorm(io, Obj);
1377 }
1378 else if (allocator) {
1379 BufPtr = allocator->Allocate<TNorm>();
1380 new (BufPtr) TNorm(io);
1381 } else {
1382 BufPtr = new TNorm(io);
1383 }
1384 }
1385
1386 ~MappingNormalizationHeap() {
1387 if ( io.outputting() ) {
1388 BufPtr->~TNorm();
1389 }
1390 else {
1391 Result = BufPtr->denormalize(io);
1392 }
1393 }
1394
1395 TNorm* operator->() { return BufPtr; }
1396
1397private:
1398 using Storage = AlignedCharArrayUnion<TNorm>;
1399
1400 Storage Buffer;
1401 IO &io;
1402 TNorm *BufPtr = nullptr;
1403 TFinal &Result;
1404};
1405
1406///
1407/// The Input class is used to parse a yaml document into in-memory structs
1408/// and vectors.
1409///
1410/// It works by using YAMLParser to do a syntax parse of the entire yaml
1411/// document, then the Input class builds a graph of HNodes which wraps
1412/// each yaml Node. The extra layer is buffering. The low level yaml
1413/// parser only lets you look at each node once. The buffering layer lets
1414/// you search and interate multiple times. This is necessary because
1415/// the mapRequired() method calls may not be in the same order
1416/// as the keys in the document.
1417///
1418class Input : public IO {
1419public:
1420 // Construct a yaml Input object from a StringRef and optional
1421 // user-data. The DiagHandler can be specified to provide
1422 // alternative error reporting.
1423 Input(StringRef InputContent,
1424 void *Ctxt = nullptr,
1425 SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1426 void *DiagHandlerCtxt = nullptr);
1427 Input(MemoryBufferRef Input,
1428 void *Ctxt = nullptr,
1429 SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1430 void *DiagHandlerCtxt = nullptr);
1431 ~Input() override;
1432
1433 // Check if there was an syntax or semantic error during parsing.
1434 std::error_code error();
1435
1436private:
1437 bool outputting() const override;
1438 bool mapTag(StringRef, bool) override;
1439 void beginMapping() override;
1440 void endMapping() override;
1441 bool preflightKey(const char *, bool, bool, bool &, void *&) override;
1442 void postflightKey(void *) override;
1443 std::vector<StringRef> keys() override;
1444 void beginFlowMapping() override;
1445 void endFlowMapping() override;
1446 unsigned beginSequence() override;
1447 void endSequence() override;
1448 bool preflightElement(unsigned index, void *&) override;
1449 void postflightElement(void *) override;
1450 unsigned beginFlowSequence() override;
1451 bool preflightFlowElement(unsigned , void *&) override;
1452 void postflightFlowElement(void *) override;
1453 void endFlowSequence() override;
1454 void beginEnumScalar() override;
1455 bool matchEnumScalar(const char*, bool) override;
1456 bool matchEnumFallback() override;
1457 void endEnumScalar() override;
1458 bool beginBitSetScalar(bool &) override;
1459 bool bitSetMatch(const char *, bool ) override;
1460 void endBitSetScalar() override;
1461 void scalarString(StringRef &, QuotingType) override;
1462 void blockScalarString(StringRef &) override;
1463 void scalarTag(std::string &) override;
1464 NodeKind getNodeKind() override;
1465 void setError(const Twine &message) override;
1466 bool canElideEmptySequence() override;
1467
1468 class HNode {
1469 virtual void anchor();
1470
1471 public:
1472 HNode(Node *n) : _node(n) { }
1473 virtual ~HNode() = default;
1474
1475 static bool classof(const HNode *) { return true; }
1476
1477 Node *_node;
1478 };
1479
1480 class EmptyHNode : public HNode {
1481 void anchor() override;
1482
1483 public:
1484 EmptyHNode(Node *n) : HNode(n) { }
1485
1486 static bool classof(const HNode *n) { return NullNode::classof(n->_node); }
1487
1488 static bool classof(const EmptyHNode *) { return true; }
1489 };
1490
1491 class ScalarHNode : public HNode {
1492 void anchor() override;
1493
1494 public:
1495 ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
1496
1497 StringRef value() const { return _value; }
1498
1499 static bool classof(const HNode *n) {
1500 return ScalarNode::classof(n->_node) ||
1501 BlockScalarNode::classof(n->_node);
1502 }
1503
1504 static bool classof(const ScalarHNode *) { return true; }
1505
1506 protected:
1507 StringRef _value;
1508 };
1509
1510 class MapHNode : public HNode {
1511 void anchor() override;
1512
1513 public:
1514 MapHNode(Node *n) : HNode(n) { }
1515
1516 static bool classof(const HNode *n) {
1517 return MappingNode::classof(n->_node);
1518 }
1519
1520 static bool classof(const MapHNode *) { return true; }
1521
1522 using NameToNodeAndLoc =
1523 StringMap<std::pair<std::unique_ptr<HNode>, SMRange>>;
1524
1525 NameToNodeAndLoc Mapping;
1526 SmallVector<std::string, 6> ValidKeys;
1527 };
1528
1529 class SequenceHNode : public HNode {
1530 void anchor() override;
1531
1532 public:
1533 SequenceHNode(Node *n) : HNode(n) { }
1534
1535 static bool classof(const HNode *n) {
1536 return SequenceNode::classof(n->_node);
1537 }
1538
1539 static bool classof(const SequenceHNode *) { return true; }
1540
1541 std::vector<std::unique_ptr<HNode>> Entries;
1542 };
1543
1544 std::unique_ptr<Input::HNode> createHNodes(Node *node);
1545 void setError(HNode *hnode, const Twine &message);
1546 void setError(Node *node, const Twine &message);
1547 void setError(const SMRange &Range, const Twine &message);
1548
1549 void reportWarning(HNode *hnode, const Twine &message);
1550 void reportWarning(Node *hnode, const Twine &message);
1551 void reportWarning(const SMRange &Range, const Twine &message);
1552
1553public:
1554 // These are only used by operator>>. They could be private
1555 // if those templated things could be made friends.
1556 bool setCurrentDocument();
1557 bool nextDocument();
1558
1559 /// Returns the current node that's being parsed by the YAML Parser.
1560 const Node *getCurrentNode() const;
1561
1562 void setAllowUnknownKeys(bool Allow) override;
1563
1564private:
1565 SourceMgr SrcMgr; // must be before Strm
1566 std::unique_ptr<llvm::yaml::Stream> Strm;
1567 std::unique_ptr<HNode> TopNode;
1568 std::error_code EC;
1569 BumpPtrAllocator StringAllocator;
1570 document_iterator DocIterator;
1571 llvm::BitVector BitValuesUsed;
1572 HNode *CurrentNode = nullptr;
1573 bool ScalarMatchFound = false;
1574 bool AllowUnknownKeys = false;
1575};
1576
1577///
1578/// The Output class is used to generate a yaml document from in-memory structs
1579/// and vectors.
1580///
1581class Output : public IO {
1582public:
1583 Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
1584 ~Output() override;
1585
1586 /// Set whether or not to output optional values which are equal
1587 /// to the default value. By default, when outputting if you attempt
1588 /// to write a value that is equal to the default, the value gets ignored.
1589 /// Sometimes, it is useful to be able to see these in the resulting YAML
1590 /// anyway.
1591 void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }
1592
1593 bool outputting() const override;
1594 bool mapTag(StringRef, bool) override;
1595 void beginMapping() override;
1596 void endMapping() override;
1597 bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
1598 void postflightKey(void *) override;
1599 std::vector<StringRef> keys() override;
1600 void beginFlowMapping() override;
1601 void endFlowMapping() override;
1602 unsigned beginSequence() override;
1603 void endSequence() override;
1604 bool preflightElement(unsigned, void *&) override;
1605 void postflightElement(void *) override;
1606 unsigned beginFlowSequence() override;
1607 bool preflightFlowElement(unsigned, void *&) override;
1608 void postflightFlowElement(void *) override;
1609 void endFlowSequence() override;
1610 void beginEnumScalar() override;
1611 bool matchEnumScalar(const char*, bool) override;
1612 bool matchEnumFallback() override;
1613 void endEnumScalar() override;
1614 bool beginBitSetScalar(bool &) override;
1615 bool bitSetMatch(const char *, bool ) override;
1616 void endBitSetScalar() override;
1617 void scalarString(StringRef &, QuotingType) override;
1618 void blockScalarString(StringRef &) override;
1619 void scalarTag(std::string &) override;
1620 NodeKind getNodeKind() override;
1621 void setError(const Twine &message) override;
1622 bool canElideEmptySequence() override;
1623
1624 // These are only used by operator<<. They could be private
1625 // if that templated operator could be made a friend.
1626 void beginDocuments();
1627 bool preflightDocument(unsigned);
1628 void postflightDocument();
1629 void endDocuments();
1630
1631private:
1632 void output(StringRef s);
1633 void outputUpToEndOfLine(StringRef s);
1634 void newLineCheck(bool EmptySequence = false);
1635 void outputNewLine();
1636 void paddedKey(StringRef key);
1637 void flowKey(StringRef Key);
1638
1639 enum InState {
1640 inSeqFirstElement,
1641 inSeqOtherElement,
1642 inFlowSeqFirstElement,
1643 inFlowSeqOtherElement,
1644 inMapFirstKey,
1645 inMapOtherKey,
1646 inFlowMapFirstKey,
1647 inFlowMapOtherKey
1648 };
1649
1650 static bool inSeqAnyElement(InState State);
1651 static bool inFlowSeqAnyElement(InState State);
1652 static bool inMapAnyKey(InState State);
1653 static bool inFlowMapAnyKey(InState State);
1654
1655 raw_ostream &Out;
1656 int WrapColumn;
1657 SmallVector<InState, 8> StateStack;
1658 int Column = 0;
1659 int ColumnAtFlowStart = 0;
1660 int ColumnAtMapFlowStart = 0;
1661 bool NeedBitValueComma = false;
1662 bool NeedFlowSequenceComma = false;
1663 bool EnumerationMatchFound = false;
1664 bool WriteDefaultValues = false;
1665 StringRef Padding;
1666 StringRef PaddingBeforeContainer;
1667};
1668
1669template <typename T, typename Context>
1670void IO::processKeyWithDefault(const char *Key, std::optional<T> &Val,
1671 const std::optional<T> &DefaultValue,
1672 bool Required, Context &Ctx) {
1673 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", 1673, __extension__
__PRETTY_FUNCTION__))
;
1674 void *SaveInfo;
1675 bool UseDefault = true;
1676 const bool sameAsDefault = outputting() && !Val;
1677 if (!outputting() && !Val)
1678 Val = T();
1679 if (Val &&
1680 this->preflightKey(Key, Required, sameAsDefault, UseDefault, SaveInfo)) {
1681
1682 // When reading an std::optional<X> key from a YAML description, we allow
1683 // the special "<none>" value, which can be used to specify that no value
1684 // was requested, i.e. the DefaultValue will be assigned. The DefaultValue
1685 // is usually None.
1686 bool IsNone = false;
1687 if (!outputting())
1688 if (const auto *Node =
1689 dyn_cast<ScalarNode>(((Input *)this)->getCurrentNode()))
1690 // We use rtrim to ignore possible white spaces that might exist when a
1691 // comment is present on the same line.
1692 IsNone = Node->getRawValue().rtrim(' ') == "<none>";
1693
1694 if (IsNone)
1695 Val = DefaultValue;
1696 else
1697 yamlize(*this, *Val, Required, Ctx);
1698 this->postflightKey(SaveInfo);
1699 } else {
1700 if (UseDefault)
1701 Val = DefaultValue;
1702 }
1703}
1704
1705/// YAML I/O does conversion based on types. But often native data types
1706/// are just a typedef of built in intergral types (e.g. int). But the C++
1707/// type matching system sees through the typedef and all the typedefed types
1708/// look like a built in type. This will cause the generic YAML I/O conversion
1709/// to be used. To provide better control over the YAML conversion, you can
1710/// use this macro instead of typedef. It will create a class with one field
1711/// and automatic conversion operators to and from the base type.
1712/// Based on BOOST_STRONG_TYPEDEF
1713#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; };
\
1714 struct _type { \
1715 _type() = default; \
1716 _type(const _base v) : value(v) {} \
1717 _type(const _type &v) = default; \
1718 _type &operator=(const _type &rhs) = default; \
1719 _type &operator=(const _base &rhs) { value = rhs; return *this; } \
1720 operator const _base & () const { return value; } \
1721 bool operator==(const _type &rhs) const { return value == rhs.value; } \
1722 bool operator==(const _base &rhs) const { return value == rhs; } \
1723 bool operator<(const _type &rhs) const { return value < rhs.value; } \
1724 _base value; \
1725 using BaseType = _base; \
1726 };
1727
1728///
1729/// Use these types instead of uintXX_t in any mapping to have
1730/// its yaml output formatted as hexadecimal.
1731///
1732LLVM_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; };
1733LLVM_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; };
1734LLVM_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; };
1735LLVM_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; };
1736
1737template<>
1738struct ScalarTraits<Hex8> {
1739 static void output(const Hex8 &, void *, raw_ostream &);
1740 static StringRef input(StringRef, void *, Hex8 &);
1741 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1742};
1743
1744template<>
1745struct ScalarTraits<Hex16> {
1746 static void output(const Hex16 &, void *, raw_ostream &);
1747 static StringRef input(StringRef, void *, Hex16 &);
1748 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1749};
1750
1751template<>
1752struct ScalarTraits<Hex32> {
1753 static void output(const Hex32 &, void *, raw_ostream &);
1754 static StringRef input(StringRef, void *, Hex32 &);
1755 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1756};
1757
1758template<>
1759struct ScalarTraits<Hex64> {
1760 static void output(const Hex64 &, void *, raw_ostream &);
1761 static StringRef input(StringRef, void *, Hex64 &);
1762 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1763};
1764
1765template <> struct ScalarTraits<VersionTuple> {
1766 static void output(const VersionTuple &Value, void *, llvm::raw_ostream &Out);
1767 static StringRef input(StringRef, void *, VersionTuple &);
1768 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1769};
1770
1771// Define non-member operator>> so that Input can stream in a document list.
1772template <typename T>
1773inline std::enable_if_t<has_DocumentListTraits<T>::value, Input &>
1774operator>>(Input &yin, T &docList) {
1775 int i = 0;
1776 EmptyContext Ctx;
1777 while ( yin.setCurrentDocument() ) {
1778 yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
1779 if ( yin.error() )
1780 return yin;
1781 yin.nextDocument();
1782 ++i;
1783 }
1784 return yin;
1785}
1786
1787// Define non-member operator>> so that Input can stream in a map as a document.
1788template <typename T>
1789inline std::enable_if_t<has_MappingTraits<T, EmptyContext>::value, Input &>
1790operator>>(Input &yin, T &docMap) {
1791 EmptyContext Ctx;
1792 yin.setCurrentDocument();
1793 yamlize(yin, docMap, true, Ctx);
1794 return yin;
1795}
1796
1797// Define non-member operator>> so that Input can stream in a sequence as
1798// a document.
1799template <typename T>
1800inline std::enable_if_t<has_SequenceTraits<T>::value, Input &>
1801operator>>(Input &yin, T &docSeq) {
1802 EmptyContext Ctx;
1803 if (yin.setCurrentDocument())
1804 yamlize(yin, docSeq, true, Ctx);
1805 return yin;
1806}
1807
1808// Define non-member operator>> so that Input can stream in a block scalar.
1809template <typename T>
1810inline std::enable_if_t<has_BlockScalarTraits<T>::value, Input &>
1811operator>>(Input &In, T &Val) {
1812 EmptyContext Ctx;
1813 if (In.setCurrentDocument())
1814 yamlize(In, Val, true, Ctx);
1815 return In;
1816}
1817
1818// Define non-member operator>> so that Input can stream in a string map.
1819template <typename T>
1820inline std::enable_if_t<has_CustomMappingTraits<T>::value, Input &>
1821operator>>(Input &In, T &Val) {
1822 EmptyContext Ctx;
1823 if (In.setCurrentDocument())
1824 yamlize(In, Val, true, Ctx);
1825 return In;
1826}
1827
1828// Define non-member operator>> so that Input can stream in a polymorphic type.
1829template <typename T>
1830inline std::enable_if_t<has_PolymorphicTraits<T>::value, Input &>
1831operator>>(Input &In, T &Val) {
1832 EmptyContext Ctx;
1833 if (In.setCurrentDocument())
1834 yamlize(In, Val, true, Ctx);
1835 return In;
1836}
1837
1838// Provide better error message about types missing a trait specialization
1839template <typename T>
1840inline std::enable_if_t<missingTraits<T, EmptyContext>::value, Input &>
1841operator>>(Input &yin, T &docSeq) {
1842 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1843 return yin;
1844}
1845
1846// Define non-member operator<< so that Output can stream out document list.
1847template <typename T>
1848inline std::enable_if_t<has_DocumentListTraits<T>::value, Output &>
1849operator<<(Output &yout, T &docList) {
1850 EmptyContext Ctx;
1851 yout.beginDocuments();
1852 const size_t count = DocumentListTraits<T>::size(yout, docList);
1853 for(size_t i=0; i < count; ++i) {
1854 if ( yout.preflightDocument(i) ) {
1855 yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
1856 Ctx);
1857 yout.postflightDocument();
1858 }
1859 }
1860 yout.endDocuments();
1861 return yout;
1862}
1863
1864// Define non-member operator<< so that Output can stream out a map.
1865template <typename T>
1866inline std::enable_if_t<has_MappingTraits<T, EmptyContext>::value, Output &>
1867operator<<(Output &yout, T &map) {
1868 EmptyContext Ctx;
1869 yout.beginDocuments();
1870 if ( yout.preflightDocument(0) ) {
1871 yamlize(yout, map, true, Ctx);
1872 yout.postflightDocument();
1873 }
1874 yout.endDocuments();
1875 return yout;
1876}
1877
1878// Define non-member operator<< so that Output can stream out a sequence.
1879template <typename T>
1880inline std::enable_if_t<has_SequenceTraits<T>::value, Output &>
1881operator<<(Output &yout, T &seq) {
1882 EmptyContext Ctx;
1883 yout.beginDocuments();
1884 if ( yout.preflightDocument(0) ) {
1885 yamlize(yout, seq, true, Ctx);
1886 yout.postflightDocument();
1887 }
1888 yout.endDocuments();
1889 return yout;
1890}
1891
1892// Define non-member operator<< so that Output can stream out a block scalar.
1893template <typename T>
1894inline std::enable_if_t<has_BlockScalarTraits<T>::value, Output &>
1895operator<<(Output &Out, T &Val) {
1896 EmptyContext Ctx;
1897 Out.beginDocuments();
1898 if (Out.preflightDocument(0)) {
1899 yamlize(Out, Val, true, Ctx);
1900 Out.postflightDocument();
1901 }
1902 Out.endDocuments();
1903 return Out;
1904}
1905
1906// Define non-member operator<< so that Output can stream out a string map.
1907template <typename T>
1908inline std::enable_if_t<has_CustomMappingTraits<T>::value, Output &>
1909operator<<(Output &Out, T &Val) {
1910 EmptyContext Ctx;
1911 Out.beginDocuments();
1912 if (Out.preflightDocument(0)) {
1913 yamlize(Out, Val, true, Ctx);
1914 Out.postflightDocument();
1915 }
1916 Out.endDocuments();
1917 return Out;
1918}
1919
1920// Define non-member operator<< so that Output can stream out a polymorphic
1921// type.
1922template <typename T>
1923inline std::enable_if_t<has_PolymorphicTraits<T>::value, Output &>
1924operator<<(Output &Out, T &Val) {
1925 EmptyContext Ctx;
1926 Out.beginDocuments();
1927 if (Out.preflightDocument(0)) {
1928 // FIXME: The parser does not support explicit documents terminated with a
1929 // plain scalar; the end-marker is included as part of the scalar token.
1930 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", 1930, __extension__
__PRETTY_FUNCTION__))
;
1931 yamlize(Out, Val, true, Ctx);
1932 Out.postflightDocument();
1933 }
1934 Out.endDocuments();
1935 return Out;
1936}
1937
1938// Provide better error message about types missing a trait specialization
1939template <typename T>
1940inline std::enable_if_t<missingTraits<T, EmptyContext>::value, Output &>
1941operator<<(Output &yout, T &seq) {
1942 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1943 return yout;
1944}
1945
1946template <bool B> struct IsFlowSequenceBase {};
1947template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
1948
1949template <typename T, typename U = void>
1950struct IsResizable : std::false_type {};
1951
1952template <typename T>
1953struct IsResizable<T, std::void_t<decltype(std::declval<T>().resize(0))>>
1954 : public std::true_type {};
1955
1956template <typename T, bool B> struct IsResizableBase {
1957 using type = typename T::value_type;
1958
1959 static type &element(IO &io, T &seq, size_t index) {
1960 if (index >= seq.size())
1961 seq.resize(index + 1);
1962 return seq[index];
1963 }
1964};
1965
1966template <typename T> struct IsResizableBase<T, false> {
1967 using type = typename T::value_type;
1968
1969 static type &element(IO &io, T &seq, size_t index) {
1970 if (index >= seq.size()) {
1971 io.setError(Twine("value sequence extends beyond static size (") +
1972 Twine(seq.size()) + ")");
1973 return seq[0];
1974 }
1975 return seq[index];
1976 }
1977};
1978
1979template <typename T, bool Flow>
1980struct SequenceTraitsImpl
1981 : IsFlowSequenceBase<Flow>, IsResizableBase<T, IsResizable<T>::value> {
1982 static size_t size(IO &io, T &seq) { return seq.size(); }
1983};
1984
1985// Simple helper to check an expression can be used as a bool-valued template
1986// argument.
1987template <bool> struct CheckIsBool { static const bool value = true; };
1988
1989// If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
1990// SequenceTraits that do the obvious thing.
1991template <typename T>
1992struct SequenceTraits<
1993 std::vector<T>,
1994 std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
1995 : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
1996template <typename T, unsigned N>
1997struct SequenceTraits<
1998 SmallVector<T, N>,
1999 std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
2000 : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
2001template <typename T>
2002struct SequenceTraits<
2003 SmallVectorImpl<T>,
2004 std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
2005 : SequenceTraitsImpl<SmallVectorImpl<T>, SequenceElementTraits<T>::flow> {};
2006template <typename T>
2007struct SequenceTraits<
2008 MutableArrayRef<T>,
2009 std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
2010 : SequenceTraitsImpl<MutableArrayRef<T>, SequenceElementTraits<T>::flow> {};
2011
2012// Sequences of fundamental types use flow formatting.
2013template <typename T>
2014struct SequenceElementTraits<T,
2015 std::enable_if_t<std::is_fundamental<T>::value>> {
2016 static const bool flow = true;
2017};
2018
2019// Sequences of strings use block formatting.
2020template<> struct SequenceElementTraits<std::string> {
2021 static const bool flow = false;
2022};
2023template<> struct SequenceElementTraits<StringRef> {
2024 static const bool flow = false;
2025};
2026template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
2027 static const bool flow = false;
2028};
2029
2030/// Implementation of CustomMappingTraits for std::map<std::string, T>.
2031template <typename T> struct StdMapStringCustomMappingTraitsImpl {
2032 using map_type = std::map<std::string, T>;
2033
2034 static void inputOne(IO &io, StringRef key, map_type &v) {
2035 io.mapRequired(key.str().c_str(), v[std::string(key)]);
2036 }
2037
2038 static void output(IO &io, map_type &v) {
2039 for (auto &p : v)
2040 io.mapRequired(p.first.c_str(), p.second);
2041 }
2042};
2043
2044} // end namespace yaml
2045} // end namespace llvm
2046
2047#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; }; } }
\
2048 namespace llvm { \
2049 namespace yaml { \
2050 static_assert( \
2051 !std::is_fundamental_v<TYPE> && !std::is_same_v<TYPE, std::string> && \
2052 !std::is_same_v<TYPE, llvm::StringRef>, \
2053 "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"); \
2054 template <> struct SequenceElementTraits<TYPE> { \
2055 static const bool flow = FLOW; \
2056 }; \
2057 } \
2058 }
2059
2060/// Utility for declaring that a std::vector of a particular type
2061/// should be considered a YAML sequence.
2062#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; }; } }
\
2063 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; }; } }
2064
2065/// Utility for declaring that a std::vector of a particular type
2066/// should be considered a YAML flow sequence.
2067#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; }; } }
\
2068 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; }; } }
2069
2070#define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type)namespace llvm { namespace yaml { template <> struct MappingTraits
<Type> { static void mapping(IO &IO, Type &Obj)
; }; } }
\
2071 namespace llvm { \
2072 namespace yaml { \
2073 template <> struct MappingTraits<Type> { \
2074 static void mapping(IO &IO, Type &Obj); \
2075 }; \
2076 } \
2077 }
2078
2079#define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<Type> { static void enumeration(IO &io, Type &
Value); }; } }
\
2080 namespace llvm { \
2081 namespace yaml { \
2082 template <> struct ScalarEnumerationTraits<Type> { \
2083 static void enumeration(IO &io, Type &Value); \
2084 }; \
2085 } \
2086 }
2087
2088#define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)namespace llvm { namespace yaml { template <> struct ScalarBitSetTraits
<Type> { static void bitset(IO &IO, Type &Options
); }; } }
\
2089 namespace llvm { \
2090 namespace yaml { \
2091 template <> struct ScalarBitSetTraits<Type> { \
2092 static void bitset(IO &IO, Type &Options); \
2093 }; \
2094 } \
2095 }
2096
2097#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; } }; } }
\
2098 namespace llvm { \
2099 namespace yaml { \
2100 template <> struct ScalarTraits<Type> { \
2101 static void output(const Type &Value, void *ctx, raw_ostream &Out); \
2102 static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \
2103 static QuotingType mustQuote(StringRef) { return MustQuote; } \
2104 }; \
2105 } \
2106 }
2107
2108/// Utility for declaring that a std::vector of a particular type
2109/// should be considered a YAML document list.
2110#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> {}; } }
\
2111 namespace llvm { \
2112 namespace yaml { \
2113 template <unsigned N> \
2114 struct DocumentListTraits<SmallVector<_type, N>> \
2115 : public SequenceTraitsImpl<SmallVector<_type, N>, false> {}; \
2116 template <> \
2117 struct DocumentListTraits<std::vector<_type>> \
2118 : public SequenceTraitsImpl<std::vector<_type>, false> {}; \
2119 } \
2120 }
2121
2122/// Utility for declaring that std::map<std::string, _type> should be considered
2123/// a YAML map.
2124#define LLVM_YAML_IS_STRING_MAP(_type)namespace llvm { namespace yaml { template <> struct CustomMappingTraits
<std::map<std::string, _type>> : public StdMapStringCustomMappingTraitsImpl
<_type> {}; } }
\
2125 namespace llvm { \
2126 namespace yaml { \
2127 template <> \
2128 struct CustomMappingTraits<std::map<std::string, _type>> \
2129 : public StdMapStringCustomMappingTraitsImpl<_type> {}; \
2130 } \
2131 }
2132
2133LLVM_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; }; } }
2134LLVM_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; }; } }
2135LLVM_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; }; } }
2136LLVM_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; }; } }
2137
2138#endif // LLVM_SUPPORT_YAMLTRAITS_H