1 //===-- ArchSpecTest.cpp --------------------------------------------------===//
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 #include "gtest/gtest.h"
10 
11 #include "lldb/Utility/ArchSpec.h"
12 #include "llvm/BinaryFormat/ELF.h"
13 #include "llvm/BinaryFormat/MachO.h"
14 #include "llvm/Support/YAMLParser.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 
TEST(ArchSpecTest,TestParseMachCPUDashSubtypeTripleSimple)19 TEST(ArchSpecTest, TestParseMachCPUDashSubtypeTripleSimple) {
20 
21   // Success conditions.  Valid cpu/subtype combinations using both - and .
22   ArchSpec AS;
23   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10", AS));
24   EXPECT_EQ(12u, AS.GetMachOCPUType());
25   EXPECT_EQ(10u, AS.GetMachOCPUSubType());
26 
27   AS = ArchSpec();
28   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15", AS));
29   EXPECT_EQ(12u, AS.GetMachOCPUType());
30   EXPECT_EQ(15u, AS.GetMachOCPUSubType());
31 
32   AS = ArchSpec();
33   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12.15", AS));
34   EXPECT_EQ(12u, AS.GetMachOCPUType());
35   EXPECT_EQ(15u, AS.GetMachOCPUSubType());
36 
37   // Failure conditions.
38 
39   // Valid string, unknown cpu/subtype.
40   AS = ArchSpec();
41   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("13.11", AS));
42   EXPECT_EQ(0u, AS.GetMachOCPUType());
43   EXPECT_EQ(0u, AS.GetMachOCPUSubType());
44 
45   // Missing / invalid cpu or subtype
46   AS = ArchSpec();
47   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13", AS));
48 
49   AS = ArchSpec();
50   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13.A", AS));
51 
52   AS = ArchSpec();
53   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("A.13", AS));
54 
55   // Empty string.
56   AS = ArchSpec();
57   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("", AS));
58 }
59 
TEST(ArchSpecTest,TestParseMachCPUDashSubtypeTripleExtra)60 TEST(ArchSpecTest, TestParseMachCPUDashSubtypeTripleExtra) {
61   ArchSpec AS;
62   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15-vendor-os", AS));
63   EXPECT_EQ(12u, AS.GetMachOCPUType());
64   EXPECT_EQ(15u, AS.GetMachOCPUSubType());
65   EXPECT_EQ("vendor", AS.GetTriple().getVendorName());
66   EXPECT_EQ("os", AS.GetTriple().getOSName());
67 
68   AS = ArchSpec();
69   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10-vendor-os-name", AS));
70   EXPECT_EQ(12u, AS.GetMachOCPUType());
71   EXPECT_EQ(10u, AS.GetMachOCPUSubType());
72   EXPECT_EQ("vendor", AS.GetTriple().getVendorName());
73   EXPECT_EQ("os", AS.GetTriple().getOSName());
74 
75   AS = ArchSpec();
76   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15-vendor.os-name", AS));
77   EXPECT_EQ(12u, AS.GetMachOCPUType());
78   EXPECT_EQ(15u, AS.GetMachOCPUSubType());
79   EXPECT_EQ("vendor.os", AS.GetTriple().getVendorName());
80   EXPECT_EQ("name", AS.GetTriple().getOSName());
81 
82   // These there should parse correctly, but the vendor / OS should be defaulted
83   // since they are unrecognized.
84   AS = ArchSpec();
85   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10-vendor", AS));
86   EXPECT_EQ(12u, AS.GetMachOCPUType());
87   EXPECT_EQ(10u, AS.GetMachOCPUSubType());
88   EXPECT_EQ("apple", AS.GetTriple().getVendorName());
89   EXPECT_EQ("", AS.GetTriple().getOSName());
90 
91   AS = ArchSpec();
92   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12.10.10", AS));
93 
94   AS = ArchSpec();
95   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12-10.10", AS));
96 }
97 
TEST(ArchSpecTest,TestSetTriple)98 TEST(ArchSpecTest, TestSetTriple) {
99   ArchSpec AS;
100 
101   // Various flavors of valid triples.
102   EXPECT_TRUE(AS.SetTriple("12-10-apple-darwin"));
103   EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_ARM), AS.GetMachOCPUType());
104   EXPECT_EQ(10u, AS.GetMachOCPUSubType());
105   EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str())
106                   .consume_front("armv7f-apple-darwin"));
107   EXPECT_EQ(ArchSpec::eCore_arm_armv7f, AS.GetCore());
108 
109   AS = ArchSpec();
110   EXPECT_TRUE(AS.SetTriple("18.100-apple-darwin"));
111   EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_POWERPC), AS.GetMachOCPUType());
112   EXPECT_EQ(100u, AS.GetMachOCPUSubType());
113   EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str())
114                   .consume_front("powerpc-apple-darwin"));
115   EXPECT_EQ(ArchSpec::eCore_ppc_ppc970, AS.GetCore());
116 
117   AS = ArchSpec();
118   EXPECT_TRUE(AS.SetTriple("i686-pc-windows"));
119   EXPECT_EQ(llvm::Triple::x86, AS.GetTriple().getArch());
120   EXPECT_EQ(llvm::Triple::PC, AS.GetTriple().getVendor());
121   EXPECT_EQ(llvm::Triple::Win32, AS.GetTriple().getOS());
122   EXPECT_TRUE(
123       llvm::StringRef(AS.GetTriple().str()).consume_front("i686-pc-windows"));
124   EXPECT_STREQ("i686", AS.GetArchitectureName());
125   EXPECT_EQ(ArchSpec::eCore_x86_32_i686, AS.GetCore());
126 
127   // Various flavors of invalid triples.
128   AS = ArchSpec();
129   EXPECT_FALSE(AS.SetTriple("unknown-unknown-unknown"));
130 
131   AS = ArchSpec();
132   EXPECT_FALSE(AS.SetTriple("unknown"));
133 
134   AS = ArchSpec();
135   EXPECT_FALSE(AS.SetTriple(""));
136 }
137 
TEST(ArchSpecTest,MergeFrom)138 TEST(ArchSpecTest, MergeFrom) {
139   {
140     ArchSpec A;
141     ArchSpec B("x86_64-pc-linux");
142 
143     EXPECT_FALSE(A.IsValid());
144     ASSERT_TRUE(B.IsValid());
145     EXPECT_EQ(llvm::Triple::ArchType::x86_64, B.GetTriple().getArch());
146     EXPECT_EQ(llvm::Triple::VendorType::PC, B.GetTriple().getVendor());
147     EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS());
148     EXPECT_EQ(ArchSpec::eCore_x86_64_x86_64, B.GetCore());
149 
150     A.MergeFrom(B);
151     ASSERT_TRUE(A.IsValid());
152     EXPECT_EQ(llvm::Triple::ArchType::x86_64, A.GetTriple().getArch());
153     EXPECT_EQ(llvm::Triple::VendorType::PC, A.GetTriple().getVendor());
154     EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS());
155     EXPECT_EQ(ArchSpec::eCore_x86_64_x86_64, A.GetCore());
156   }
157   {
158     ArchSpec A("aarch64");
159     ArchSpec B("aarch64--linux-android");
160 
161     ArchSpec C("arm64_32");
162     ArchSpec D("arm64_32--watchos");
163 
164     EXPECT_TRUE(A.IsValid());
165     EXPECT_TRUE(B.IsValid());
166     EXPECT_TRUE(C.IsValid());
167     EXPECT_TRUE(D.IsValid());
168 
169     EXPECT_EQ(llvm::Triple::ArchType::aarch64, B.GetTriple().getArch());
170     EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
171               B.GetTriple().getVendor());
172     EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS());
173     EXPECT_EQ(llvm::Triple::EnvironmentType::Android,
174               B.GetTriple().getEnvironment());
175 
176     A.MergeFrom(B);
177     EXPECT_EQ(llvm::Triple::ArchType::aarch64, A.GetTriple().getArch());
178     EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
179               A.GetTriple().getVendor());
180     EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS());
181     EXPECT_EQ(llvm::Triple::EnvironmentType::Android,
182               A.GetTriple().getEnvironment());
183 
184     EXPECT_EQ(llvm::Triple::ArchType::aarch64_32, D.GetTriple().getArch());
185     EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
186               D.GetTriple().getVendor());
187     EXPECT_EQ(llvm::Triple::OSType::WatchOS, D.GetTriple().getOS());
188 
189     C.MergeFrom(D);
190     EXPECT_EQ(llvm::Triple::ArchType::aarch64_32, C.GetTriple().getArch());
191     EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
192               C.GetTriple().getVendor());
193     EXPECT_EQ(llvm::Triple::OSType::WatchOS, C.GetTriple().getOS());
194   }
195   {
196     ArchSpec A, B;
197     A.SetArchitecture(eArchTypeELF, llvm::ELF::EM_ARM,
198                       LLDB_INVALID_CPUTYPE, llvm::ELF::ELFOSABI_NONE);
199     B.SetArchitecture(eArchTypeELF, llvm::ELF::EM_ARM,
200                       LLDB_INVALID_CPUTYPE, llvm::ELF::ELFOSABI_LINUX);
201 
202     EXPECT_TRUE(A.IsValid());
203     EXPECT_TRUE(B.IsValid());
204 
205     EXPECT_EQ(llvm::Triple::ArchType::arm, B.GetTriple().getArch());
206     EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
207               B.GetTriple().getVendor());
208     EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS());
209     EXPECT_EQ(llvm::Triple::EnvironmentType::UnknownEnvironment,
210               B.GetTriple().getEnvironment());
211 
212     A.MergeFrom(B);
213     EXPECT_EQ(llvm::Triple::ArchType::arm, A.GetTriple().getArch());
214     EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
215               A.GetTriple().getVendor());
216     EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS());
217     EXPECT_EQ(llvm::Triple::EnvironmentType::UnknownEnvironment,
218               A.GetTriple().getEnvironment());
219   }
220   {
221     ArchSpec A("arm--linux-eabihf");
222     ArchSpec B("armv8l--linux-gnueabihf");
223 
224     EXPECT_TRUE(A.IsValid());
225     EXPECT_TRUE(B.IsValid());
226 
227     EXPECT_EQ(llvm::Triple::ArchType::arm, A.GetTriple().getArch());
228     EXPECT_EQ(llvm::Triple::ArchType::arm, B.GetTriple().getArch());
229 
230     EXPECT_EQ(ArchSpec::eCore_arm_generic, A.GetCore());
231     EXPECT_EQ(ArchSpec::eCore_arm_armv8l, B.GetCore());
232 
233     EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
234               A.GetTriple().getVendor());
235     EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
236               B.GetTriple().getVendor());
237 
238     EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS());
239     EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS());
240 
241     EXPECT_EQ(llvm::Triple::EnvironmentType::EABIHF,
242               A.GetTriple().getEnvironment());
243     EXPECT_EQ(llvm::Triple::EnvironmentType::GNUEABIHF,
244               B.GetTriple().getEnvironment());
245 
246     A.MergeFrom(B);
247     EXPECT_EQ(llvm::Triple::ArchType::arm, A.GetTriple().getArch());
248     EXPECT_EQ(ArchSpec::eCore_arm_armv8l, A.GetCore());
249     EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
250               A.GetTriple().getVendor());
251     EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS());
252     EXPECT_EQ(llvm::Triple::EnvironmentType::EABIHF,
253               A.GetTriple().getEnvironment());
254   }
255 }
256 
TEST(ArchSpecTest,MergeFromMachOUnknown)257 TEST(ArchSpecTest, MergeFromMachOUnknown) {
258   class MyArchSpec : public ArchSpec {
259   public:
260     MyArchSpec() {
261       this->SetTriple("unknown-mach-64");
262       this->m_core = ArchSpec::eCore_uknownMach64;
263       this->m_byte_order = eByteOrderLittle;
264       this->m_flags = 0;
265     }
266   };
267 
268   MyArchSpec A;
269   ASSERT_TRUE(A.IsValid());
270   MyArchSpec B;
271   ASSERT_TRUE(B.IsValid());
272   A.MergeFrom(B);
273   ASSERT_EQ(A.GetCore(), ArchSpec::eCore_uknownMach64);
274 }
275 
TEST(ArchSpecTest,Compatibility)276 TEST(ArchSpecTest, Compatibility) {
277   {
278     ArchSpec A("x86_64-apple-macosx10.12");
279     ArchSpec B("x86_64-apple-macosx10.12");
280     ASSERT_TRUE(A.IsExactMatch(B));
281     ASSERT_TRUE(A.IsCompatibleMatch(B));
282   }
283   {
284     // The version information is auxiliary to support availability but
285     // doesn't affect compatibility.
286     ArchSpec A("x86_64-apple-macosx10.11");
287     ArchSpec B("x86_64-apple-macosx10.12");
288     ASSERT_TRUE(A.IsExactMatch(B));
289     ASSERT_TRUE(A.IsCompatibleMatch(B));
290   }
291   {
292     ArchSpec A("x86_64-apple-macosx10.13");
293     ArchSpec B("x86_64h-apple-macosx10.13");
294     ASSERT_FALSE(A.IsExactMatch(B));
295     ASSERT_TRUE(A.IsCompatibleMatch(B));
296   }
297   {
298     ArchSpec A("x86_64-apple-macosx");
299     ArchSpec B("x86_64-apple-ios-simulator");
300     ASSERT_FALSE(A.IsExactMatch(B));
301     ASSERT_FALSE(A.IsCompatibleMatch(B));
302   }
303   {
304     ArchSpec A("x86_64-*-*");
305     ArchSpec B("x86_64-apple-ios-simulator");
306     ASSERT_FALSE(A.IsExactMatch(B));
307     ASSERT_FALSE(A.IsCompatibleMatch(B));
308     ASSERT_FALSE(B.IsExactMatch(A));
309     ASSERT_FALSE(B.IsCompatibleMatch(A));
310   }
311   {
312     ArchSpec A("x86_64-apple-ios");
313     ArchSpec B("x86_64-apple-ios-simulator");
314     ASSERT_FALSE(A.IsExactMatch(B));
315     ASSERT_FALSE(A.IsCompatibleMatch(B));
316     ASSERT_FALSE(B.IsExactMatch(A));
317     ASSERT_FALSE(B.IsCompatibleMatch(A));
318   }
319   {
320     // FIXME: This is surprisingly not equivalent to "x86_64-*-*".
321     ArchSpec A("x86_64");
322     ArchSpec B("x86_64-apple-ios-simulator");
323     ASSERT_FALSE(A.IsExactMatch(B));
324     ASSERT_TRUE(A.IsCompatibleMatch(B));
325     ASSERT_FALSE(B.IsExactMatch(A));
326     ASSERT_TRUE(B.IsCompatibleMatch(A));
327   }
328   {
329     ArchSpec A("arm64-apple-ios");
330     ArchSpec B("arm64-apple-ios-simulator");
331     ASSERT_FALSE(A.IsExactMatch(B));
332     ASSERT_FALSE(A.IsCompatibleMatch(B));
333     ASSERT_FALSE(B.IsCompatibleMatch(A));
334     ASSERT_FALSE(B.IsCompatibleMatch(A));
335   }
336   {
337     ArchSpec A("arm64-*-*");
338     ArchSpec B("arm64-apple-ios");
339     ASSERT_FALSE(A.IsExactMatch(B));
340     // FIXME: This looks unintuitive and we should investigate whether
341     // this is the desired behavior.
342     ASSERT_FALSE(A.IsCompatibleMatch(B));
343   }
344   {
345     ArchSpec A("x86_64-*-*");
346     ArchSpec B("x86_64-apple-ios-simulator");
347     ASSERT_FALSE(A.IsExactMatch(B));
348     // FIXME: See above, though the extra environment complicates things.
349     ASSERT_FALSE(A.IsCompatibleMatch(B));
350   }
351   {
352     ArchSpec A("x86_64");
353     ArchSpec B("x86_64-apple-macosx10.14");
354     // FIXME: The exact match also looks unintuitive.
355     ASSERT_TRUE(A.IsExactMatch(B));
356     ASSERT_TRUE(A.IsCompatibleMatch(B));
357   }
358   {
359     ArchSpec A("x86_64");
360     ArchSpec B("x86_64-apple-ios12.0.0-macabi");
361     // FIXME: The exact match also looks unintuitive.
362     ASSERT_TRUE(A.IsExactMatch(B));
363     ASSERT_TRUE(A.IsCompatibleMatch(B));
364   }
365   {
366     ArchSpec A("x86_64-apple-ios12.0.0");
367     ArchSpec B("x86_64-apple-ios12.0.0-macabi");
368     ASSERT_FALSE(A.IsExactMatch(B));
369     ASSERT_FALSE(A.IsCompatibleMatch(B));
370   }
371   {
372     ArchSpec A("x86_64-apple-macosx10.14.2");
373     ArchSpec B("x86_64-apple-ios12.0.0-macabi");
374     ASSERT_FALSE(A.IsExactMatch(B));
375     ASSERT_TRUE(A.IsCompatibleMatch(B));
376   }
377   {
378     ArchSpec A("x86_64-apple-macosx10.14.2");
379     ArchSpec B("x86_64-apple-ios12.0.0-macabi");
380     // ios-macabi wins.
381     A.MergeFrom(B);
382     ASSERT_TRUE(A.IsExactMatch(B));
383   }
384   {
385     ArchSpec A("x86_64-apple-macosx10.14.2");
386     ArchSpec B("x86_64-apple-ios12.0.0-macabi");
387     ArchSpec C(B);
388     // ios-macabi wins.
389     B.MergeFrom(A);
390     ASSERT_TRUE(B.IsExactMatch(C));
391   }
392 }
393 
TEST(ArchSpecTest,OperatorBool)394 TEST(ArchSpecTest, OperatorBool) {
395   EXPECT_FALSE(ArchSpec());
396   EXPECT_TRUE(ArchSpec("x86_64-pc-linux"));
397 }
398 
TEST(ArchSpecTest,TripleComponentsWereSpecified)399 TEST(ArchSpecTest, TripleComponentsWereSpecified) {
400   {
401     ArchSpec A("");
402     ArchSpec B("-");
403     ArchSpec C("--");
404     ArchSpec D("---");
405 
406     ASSERT_FALSE(A.TripleVendorWasSpecified());
407     ASSERT_FALSE(A.TripleOSWasSpecified());
408     ASSERT_FALSE(A.TripleEnvironmentWasSpecified());
409 
410     ASSERT_FALSE(B.TripleVendorWasSpecified());
411     ASSERT_FALSE(B.TripleOSWasSpecified());
412     ASSERT_FALSE(B.TripleEnvironmentWasSpecified());
413 
414     ASSERT_FALSE(C.TripleVendorWasSpecified());
415     ASSERT_FALSE(C.TripleOSWasSpecified());
416     ASSERT_FALSE(C.TripleEnvironmentWasSpecified());
417 
418     ASSERT_FALSE(D.TripleVendorWasSpecified());
419     ASSERT_FALSE(D.TripleOSWasSpecified());
420     ASSERT_FALSE(D.TripleEnvironmentWasSpecified());
421   }
422   {
423     // TODO: llvm::Triple::normalize treats the missing components from these
424     // triples as specified unknown components instead of unspecified
425     // components. We need to either change the behavior in llvm or work around
426     // this in lldb.
427     ArchSpec A("armv7");
428     ArchSpec B("armv7-");
429     ArchSpec C("armv7--");
430     ArchSpec D("armv7---");
431 
432     ASSERT_FALSE(A.TripleVendorWasSpecified());
433     ASSERT_FALSE(A.TripleOSWasSpecified());
434     ASSERT_FALSE(A.TripleEnvironmentWasSpecified());
435 
436     ASSERT_TRUE(B.TripleVendorWasSpecified());
437     ASSERT_FALSE(B.TripleOSWasSpecified());
438     ASSERT_FALSE(B.TripleEnvironmentWasSpecified());
439 
440     ASSERT_TRUE(C.TripleVendorWasSpecified());
441     ASSERT_TRUE(C.TripleOSWasSpecified());
442     ASSERT_FALSE(C.TripleEnvironmentWasSpecified());
443 
444     ASSERT_TRUE(D.TripleVendorWasSpecified());
445     ASSERT_TRUE(D.TripleOSWasSpecified());
446     ASSERT_TRUE(D.TripleEnvironmentWasSpecified());
447   }
448   {
449     ArchSpec A("x86_64-unknown");
450     ArchSpec B("powerpc-unknown-linux");
451     ArchSpec C("i386-pc-windows-msvc");
452     ArchSpec D("aarch64-unknown-linux-android");
453 
454     ASSERT_TRUE(A.TripleVendorWasSpecified());
455     ASSERT_FALSE(A.TripleOSWasSpecified());
456     ASSERT_FALSE(A.TripleEnvironmentWasSpecified());
457 
458     ASSERT_TRUE(B.TripleVendorWasSpecified());
459     ASSERT_TRUE(B.TripleOSWasSpecified());
460     ASSERT_FALSE(B.TripleEnvironmentWasSpecified());
461 
462     ASSERT_TRUE(C.TripleVendorWasSpecified());
463     ASSERT_TRUE(C.TripleOSWasSpecified());
464     ASSERT_TRUE(C.TripleEnvironmentWasSpecified());
465 
466     ASSERT_TRUE(D.TripleVendorWasSpecified());
467     ASSERT_TRUE(D.TripleOSWasSpecified());
468     ASSERT_TRUE(D.TripleEnvironmentWasSpecified());
469   }
470 }
471 
TEST(ArchSpecTest,YAML)472 TEST(ArchSpecTest, YAML) {
473   std::string buffer;
474   llvm::raw_string_ostream os(buffer);
475 
476   // Serialize.
477   llvm::yaml::Output yout(os);
478   std::vector<ArchSpec> archs = {ArchSpec("x86_64-pc-linux"),
479                                  ArchSpec("x86_64-apple-macosx10.12"),
480                                  ArchSpec("i686-pc-windows")};
481   yout << archs;
482   os.flush();
483 
484   // Deserialize.
485   std::vector<ArchSpec> deserialized;
486   llvm::yaml::Input yin(buffer);
487   yin >> deserialized;
488 
489   EXPECT_EQ(archs, deserialized);
490 }
491