1 //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/SmallVector.h"
10 #include "llvm/ADT/StringRef.h"
11 #include "llvm/ADT/StringSwitch.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/BinaryFormat/MachO.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCDirectives.h"
16 #include "llvm/MC/MCParser/MCAsmLexer.h"
17 #include "llvm/MC/MCParser/MCAsmParser.h"
18 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
19 #include "llvm/MC/MCSectionMachO.h"
20 #include "llvm/MC/MCStreamer.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/MC/SectionKind.h"
23 #include "llvm/Support/Error.h"
24 #include "llvm/Support/FileSystem.h"
25 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/Support/SMLoc.h"
27 #include "llvm/Support/SourceMgr.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include "llvm/TargetParser/Triple.h"
33 #include <system_error>
40 /// Implementation of directive handling which is shared across all
42 class DarwinAsmParser
: public MCAsmParserExtension
{
43 template<bool (DarwinAsmParser::*HandlerMethod
)(StringRef
, SMLoc
)>
44 void addDirectiveHandler(StringRef Directive
) {
45 MCAsmParser::ExtensionDirectiveHandler Handler
= std::make_pair(
46 this, HandleDirective
<DarwinAsmParser
, HandlerMethod
>);
47 getParser().addDirectiveHandler(Directive
, Handler
);
50 bool parseSectionSwitch(StringRef Segment
, StringRef Section
,
51 unsigned TAA
= 0, unsigned ImplicitAlign
= 0,
52 unsigned StubSize
= 0);
54 SMLoc LastVersionDirective
;
57 DarwinAsmParser() = default;
59 void Initialize(MCAsmParser
&Parser
) override
{
60 // Call the base implementation.
61 this->MCAsmParserExtension::Initialize(Parser
);
63 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveAltEntry
>(".alt_entry");
64 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveDesc
>(".desc");
65 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveIndirectSymbol
>(
67 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveLsym
>(".lsym");
68 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols
>(
69 ".subsections_via_symbols");
70 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveDumpOrLoad
>(".dump");
71 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveDumpOrLoad
>(".load");
72 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveSection
>(".section");
73 addDirectiveHandler
<&DarwinAsmParser::parseDirectivePushSection
>(
75 addDirectiveHandler
<&DarwinAsmParser::parseDirectivePopSection
>(
77 addDirectiveHandler
<&DarwinAsmParser::parseDirectivePrevious
>(".previous");
78 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveSecureLogUnique
>(
79 ".secure_log_unique");
80 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveSecureLogReset
>(
82 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveTBSS
>(".tbss");
83 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveZerofill
>(".zerofill");
85 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveDataRegion
>(
87 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveDataRegionEnd
>(
90 // Special section directives.
91 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveBss
>(".bss");
92 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveConst
>(".const");
93 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveConstData
>(
95 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveConstructor
>(
97 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveCString
>(
99 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveData
>(".data");
100 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveDestructor
>(
102 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveDyld
>(".dyld");
103 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0
>(
105 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1
>(
108 &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers
>(
109 ".lazy_symbol_pointer");
110 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveLinkerOption
>(
112 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveLiteral16
>(
114 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveLiteral4
>(
116 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveLiteral8
>(
118 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveModInitFunc
>(
120 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveModTermFunc
>(
123 &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers
>(
124 ".non_lazy_symbol_pointer");
126 &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers
>(
127 ".thread_local_variable_pointer");
128 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth
>(
129 ".objc_cat_cls_meth");
130 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth
>(
131 ".objc_cat_inst_meth");
132 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCCategory
>(
134 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCClass
>(
136 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCClassNames
>(
137 ".objc_class_names");
138 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCClassVars
>(
140 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth
>(
142 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs
>(
144 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth
>(
147 &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars
>(
148 ".objc_instance_vars");
149 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs
>(
150 ".objc_message_refs");
151 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass
>(
154 &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames
>(
155 ".objc_meth_var_names");
157 &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes
>(
158 ".objc_meth_var_types");
159 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo
>(
160 ".objc_module_info");
161 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCProtocol
>(
164 &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs
>(
165 ".objc_selector_strs");
167 &DarwinAsmParser::parseSectionDirectiveObjCStringObject
>(
168 ".objc_string_object");
169 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCSymbols
>(
171 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectivePICSymbolStub
>(
173 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveStaticConst
>(
175 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveStaticData
>(
177 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveSymbolStub
>(
179 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveTData
>(".tdata");
180 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveText
>(".text");
181 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc
>(
182 ".thread_init_func");
183 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveTLV
>(".tlv");
185 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveIdent
>(".ident");
186 addDirectiveHandler
<&DarwinAsmParser::parseWatchOSVersionMin
>(
187 ".watchos_version_min");
188 addDirectiveHandler
<&DarwinAsmParser::parseTvOSVersionMin
>(
189 ".tvos_version_min");
190 addDirectiveHandler
<&DarwinAsmParser::parseIOSVersionMin
>(
192 addDirectiveHandler
<&DarwinAsmParser::parseMacOSXVersionMin
>(
193 ".macosx_version_min");
194 addDirectiveHandler
<&DarwinAsmParser::parseBuildVersion
>(".build_version");
195 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveCGProfile
>(
198 LastVersionDirective
= SMLoc();
201 bool parseDirectiveAltEntry(StringRef
, SMLoc
);
202 bool parseDirectiveDesc(StringRef
, SMLoc
);
203 bool parseDirectiveIndirectSymbol(StringRef
, SMLoc
);
204 bool parseDirectiveDumpOrLoad(StringRef
, SMLoc
);
205 bool parseDirectiveLsym(StringRef
, SMLoc
);
206 bool parseDirectiveLinkerOption(StringRef
, SMLoc
);
207 bool parseDirectiveSection(StringRef
, SMLoc
);
208 bool parseDirectivePushSection(StringRef
, SMLoc
);
209 bool parseDirectivePopSection(StringRef
, SMLoc
);
210 bool parseDirectivePrevious(StringRef
, SMLoc
);
211 bool parseDirectiveSecureLogReset(StringRef
, SMLoc
);
212 bool parseDirectiveSecureLogUnique(StringRef
, SMLoc
);
213 bool parseDirectiveSubsectionsViaSymbols(StringRef
, SMLoc
);
214 bool parseDirectiveTBSS(StringRef
, SMLoc
);
215 bool parseDirectiveZerofill(StringRef
, SMLoc
);
216 bool parseDirectiveDataRegion(StringRef
, SMLoc
);
217 bool parseDirectiveDataRegionEnd(StringRef
, SMLoc
);
219 // Named Section Directive
220 bool parseSectionDirectiveBss(StringRef
, SMLoc
) {
221 return parseSectionSwitch("__DATA", "__bss");
224 bool parseSectionDirectiveConst(StringRef
, SMLoc
) {
225 return parseSectionSwitch("__TEXT", "__const");
228 bool parseSectionDirectiveStaticConst(StringRef
, SMLoc
) {
229 return parseSectionSwitch("__TEXT", "__static_const");
232 bool parseSectionDirectiveCString(StringRef
, SMLoc
) {
233 return parseSectionSwitch("__TEXT","__cstring",
234 MachO::S_CSTRING_LITERALS
);
237 bool parseSectionDirectiveLiteral4(StringRef
, SMLoc
) {
238 return parseSectionSwitch("__TEXT", "__literal4",
239 MachO::S_4BYTE_LITERALS
, 4);
242 bool parseSectionDirectiveLiteral8(StringRef
, SMLoc
) {
243 return parseSectionSwitch("__TEXT", "__literal8",
244 MachO::S_8BYTE_LITERALS
, 8);
247 bool parseSectionDirectiveLiteral16(StringRef
, SMLoc
) {
248 return parseSectionSwitch("__TEXT","__literal16",
249 MachO::S_16BYTE_LITERALS
, 16);
252 bool parseSectionDirectiveConstructor(StringRef
, SMLoc
) {
253 return parseSectionSwitch("__TEXT","__constructor");
256 bool parseSectionDirectiveDestructor(StringRef
, SMLoc
) {
257 return parseSectionSwitch("__TEXT","__destructor");
260 bool parseSectionDirectiveFVMLibInit0(StringRef
, SMLoc
) {
261 return parseSectionSwitch("__TEXT","__fvmlib_init0");
264 bool parseSectionDirectiveFVMLibInit1(StringRef
, SMLoc
) {
265 return parseSectionSwitch("__TEXT","__fvmlib_init1");
268 bool parseSectionDirectiveSymbolStub(StringRef
, SMLoc
) {
269 return parseSectionSwitch("__TEXT","__symbol_stub",
270 MachO::S_SYMBOL_STUBS
|
271 MachO::S_ATTR_PURE_INSTRUCTIONS
,
272 // FIXME: Different on PPC and ARM.
276 bool parseSectionDirectivePICSymbolStub(StringRef
, SMLoc
) {
277 return parseSectionSwitch("__TEXT","__picsymbol_stub",
278 MachO::S_SYMBOL_STUBS
|
279 MachO::S_ATTR_PURE_INSTRUCTIONS
, 0, 26);
282 bool parseSectionDirectiveData(StringRef
, SMLoc
) {
283 return parseSectionSwitch("__DATA", "__data");
286 bool parseSectionDirectiveStaticData(StringRef
, SMLoc
) {
287 return parseSectionSwitch("__DATA", "__static_data");
290 bool parseSectionDirectiveNonLazySymbolPointers(StringRef
, SMLoc
) {
291 return parseSectionSwitch("__DATA", "__nl_symbol_ptr",
292 MachO::S_NON_LAZY_SYMBOL_POINTERS
, 4);
295 bool parseSectionDirectiveLazySymbolPointers(StringRef
, SMLoc
) {
296 return parseSectionSwitch("__DATA", "__la_symbol_ptr",
297 MachO::S_LAZY_SYMBOL_POINTERS
, 4);
300 bool parseSectionDirectiveThreadLocalVariablePointers(StringRef
, SMLoc
) {
301 return parseSectionSwitch("__DATA", "__thread_ptr",
302 MachO::S_THREAD_LOCAL_VARIABLE_POINTERS
, 4);
305 bool parseSectionDirectiveDyld(StringRef
, SMLoc
) {
306 return parseSectionSwitch("__DATA", "__dyld");
309 bool parseSectionDirectiveModInitFunc(StringRef
, SMLoc
) {
310 return parseSectionSwitch("__DATA", "__mod_init_func",
311 MachO::S_MOD_INIT_FUNC_POINTERS
, 4);
314 bool parseSectionDirectiveModTermFunc(StringRef
, SMLoc
) {
315 return parseSectionSwitch("__DATA", "__mod_term_func",
316 MachO::S_MOD_TERM_FUNC_POINTERS
, 4);
319 bool parseSectionDirectiveConstData(StringRef
, SMLoc
) {
320 return parseSectionSwitch("__DATA", "__const");
323 bool parseSectionDirectiveObjCClass(StringRef
, SMLoc
) {
324 return parseSectionSwitch("__OBJC", "__class",
325 MachO::S_ATTR_NO_DEAD_STRIP
);
328 bool parseSectionDirectiveObjCMetaClass(StringRef
, SMLoc
) {
329 return parseSectionSwitch("__OBJC", "__meta_class",
330 MachO::S_ATTR_NO_DEAD_STRIP
);
333 bool parseSectionDirectiveObjCCatClsMeth(StringRef
, SMLoc
) {
334 return parseSectionSwitch("__OBJC", "__cat_cls_meth",
335 MachO::S_ATTR_NO_DEAD_STRIP
);
338 bool parseSectionDirectiveObjCCatInstMeth(StringRef
, SMLoc
) {
339 return parseSectionSwitch("__OBJC", "__cat_inst_meth",
340 MachO::S_ATTR_NO_DEAD_STRIP
);
343 bool parseSectionDirectiveObjCProtocol(StringRef
, SMLoc
) {
344 return parseSectionSwitch("__OBJC", "__protocol",
345 MachO::S_ATTR_NO_DEAD_STRIP
);
348 bool parseSectionDirectiveObjCStringObject(StringRef
, SMLoc
) {
349 return parseSectionSwitch("__OBJC", "__string_object",
350 MachO::S_ATTR_NO_DEAD_STRIP
);
353 bool parseSectionDirectiveObjCClsMeth(StringRef
, SMLoc
) {
354 return parseSectionSwitch("__OBJC", "__cls_meth",
355 MachO::S_ATTR_NO_DEAD_STRIP
);
358 bool parseSectionDirectiveObjCInstMeth(StringRef
, SMLoc
) {
359 return parseSectionSwitch("__OBJC", "__inst_meth",
360 MachO::S_ATTR_NO_DEAD_STRIP
);
363 bool parseSectionDirectiveObjCClsRefs(StringRef
, SMLoc
) {
364 return parseSectionSwitch("__OBJC", "__cls_refs",
365 MachO::S_ATTR_NO_DEAD_STRIP
|
366 MachO::S_LITERAL_POINTERS
, 4);
369 bool parseSectionDirectiveObjCMessageRefs(StringRef
, SMLoc
) {
370 return parseSectionSwitch("__OBJC", "__message_refs",
371 MachO::S_ATTR_NO_DEAD_STRIP
|
372 MachO::S_LITERAL_POINTERS
, 4);
375 bool parseSectionDirectiveObjCSymbols(StringRef
, SMLoc
) {
376 return parseSectionSwitch("__OBJC", "__symbols",
377 MachO::S_ATTR_NO_DEAD_STRIP
);
380 bool parseSectionDirectiveObjCCategory(StringRef
, SMLoc
) {
381 return parseSectionSwitch("__OBJC", "__category",
382 MachO::S_ATTR_NO_DEAD_STRIP
);
385 bool parseSectionDirectiveObjCClassVars(StringRef
, SMLoc
) {
386 return parseSectionSwitch("__OBJC", "__class_vars",
387 MachO::S_ATTR_NO_DEAD_STRIP
);
390 bool parseSectionDirectiveObjCInstanceVars(StringRef
, SMLoc
) {
391 return parseSectionSwitch("__OBJC", "__instance_vars",
392 MachO::S_ATTR_NO_DEAD_STRIP
);
395 bool parseSectionDirectiveObjCModuleInfo(StringRef
, SMLoc
) {
396 return parseSectionSwitch("__OBJC", "__module_info",
397 MachO::S_ATTR_NO_DEAD_STRIP
);
400 bool parseSectionDirectiveObjCClassNames(StringRef
, SMLoc
) {
401 return parseSectionSwitch("__TEXT", "__cstring",
402 MachO::S_CSTRING_LITERALS
);
405 bool parseSectionDirectiveObjCMethVarTypes(StringRef
, SMLoc
) {
406 return parseSectionSwitch("__TEXT", "__cstring",
407 MachO::S_CSTRING_LITERALS
);
410 bool parseSectionDirectiveObjCMethVarNames(StringRef
, SMLoc
) {
411 return parseSectionSwitch("__TEXT", "__cstring",
412 MachO::S_CSTRING_LITERALS
);
415 bool parseSectionDirectiveObjCSelectorStrs(StringRef
, SMLoc
) {
416 return parseSectionSwitch("__OBJC", "__selector_strs",
417 MachO::S_CSTRING_LITERALS
);
420 bool parseSectionDirectiveTData(StringRef
, SMLoc
) {
421 return parseSectionSwitch("__DATA", "__thread_data",
422 MachO::S_THREAD_LOCAL_REGULAR
);
425 bool parseSectionDirectiveText(StringRef
, SMLoc
) {
426 return parseSectionSwitch("__TEXT", "__text",
427 MachO::S_ATTR_PURE_INSTRUCTIONS
);
430 bool parseSectionDirectiveTLV(StringRef
, SMLoc
) {
431 return parseSectionSwitch("__DATA", "__thread_vars",
432 MachO::S_THREAD_LOCAL_VARIABLES
);
435 bool parseSectionDirectiveIdent(StringRef
, SMLoc
) {
436 // Darwin silently ignores the .ident directive.
437 getParser().eatToEndOfStatement();
441 bool parseSectionDirectiveThreadInitFunc(StringRef
, SMLoc
) {
442 return parseSectionSwitch("__DATA", "__thread_init",
443 MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS
);
446 bool parseWatchOSVersionMin(StringRef Directive
, SMLoc Loc
) {
447 return parseVersionMin(Directive
, Loc
, MCVM_WatchOSVersionMin
);
449 bool parseTvOSVersionMin(StringRef Directive
, SMLoc Loc
) {
450 return parseVersionMin(Directive
, Loc
, MCVM_TvOSVersionMin
);
452 bool parseIOSVersionMin(StringRef Directive
, SMLoc Loc
) {
453 return parseVersionMin(Directive
, Loc
, MCVM_IOSVersionMin
);
455 bool parseMacOSXVersionMin(StringRef Directive
, SMLoc Loc
) {
456 return parseVersionMin(Directive
, Loc
, MCVM_OSXVersionMin
);
459 bool parseBuildVersion(StringRef Directive
, SMLoc Loc
);
460 bool parseVersionMin(StringRef Directive
, SMLoc Loc
, MCVersionMinType Type
);
461 bool parseMajorMinorVersionComponent(unsigned *Major
, unsigned *Minor
,
462 const char *VersionName
);
463 bool parseOptionalTrailingVersionComponent(unsigned *Component
,
464 const char *ComponentName
);
465 bool parseVersion(unsigned *Major
, unsigned *Minor
, unsigned *Update
);
466 bool parseSDKVersion(VersionTuple
&SDKVersion
);
467 void checkVersion(StringRef Directive
, StringRef Arg
, SMLoc Loc
,
468 Triple::OSType ExpectedOS
);
469 bool parseDirectiveCGProfile(StringRef Directive
, SMLoc Loc
);
472 } // end anonymous namespace
474 bool DarwinAsmParser::parseSectionSwitch(StringRef Segment
, StringRef Section
,
475 unsigned TAA
, unsigned Alignment
,
477 if (getLexer().isNot(AsmToken::EndOfStatement
))
478 return TokError("unexpected token in section switching directive");
481 // FIXME: Arch specific.
482 bool isText
= TAA
& MachO::S_ATTR_PURE_INSTRUCTIONS
;
483 getStreamer().switchSection(getContext().getMachOSection(
484 Segment
, Section
, TAA
, StubSize
,
485 isText
? SectionKind::getText() : SectionKind::getData()));
487 // Set the implicit alignment, if any.
489 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
490 // alignment on the section (e.g., if one manually inserts bytes into the
491 // section, then just issuing the section switch directive will not realign
492 // the section. However, this is arguably more reasonable behavior, and there
493 // is no good reason for someone to intentionally emit incorrectly sized
494 // values into the implicitly aligned sections.
496 getStreamer().emitValueToAlignment(Align(Alignment
));
501 /// parseDirectiveAltEntry
502 /// ::= .alt_entry identifier
503 bool DarwinAsmParser::parseDirectiveAltEntry(StringRef
, SMLoc
) {
505 if (getParser().parseIdentifier(Name
))
506 return TokError("expected identifier in directive");
509 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
511 if (Sym
->isDefined())
512 return TokError(".alt_entry must preceed symbol definition");
514 if (!getStreamer().emitSymbolAttribute(Sym
, MCSA_AltEntry
))
515 return TokError("unable to emit symbol attribute");
521 /// parseDirectiveDesc
522 /// ::= .desc identifier , expression
523 bool DarwinAsmParser::parseDirectiveDesc(StringRef
, SMLoc
) {
525 if (getParser().parseIdentifier(Name
))
526 return TokError("expected identifier in directive");
528 // Handle the identifier as the key symbol.
529 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
531 if (getLexer().isNot(AsmToken::Comma
))
532 return TokError("unexpected token in '.desc' directive");
536 if (getParser().parseAbsoluteExpression(DescValue
))
539 if (getLexer().isNot(AsmToken::EndOfStatement
))
540 return TokError("unexpected token in '.desc' directive");
544 // Set the n_desc field of this Symbol to this DescValue
545 getStreamer().emitSymbolDesc(Sym
, DescValue
);
550 /// parseDirectiveIndirectSymbol
551 /// ::= .indirect_symbol identifier
552 bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef
, SMLoc Loc
) {
553 const MCSectionMachO
*Current
= static_cast<const MCSectionMachO
*>(
554 getStreamer().getCurrentSectionOnly());
555 MachO::SectionType SectionType
= Current
->getType();
556 if (SectionType
!= MachO::S_NON_LAZY_SYMBOL_POINTERS
&&
557 SectionType
!= MachO::S_LAZY_SYMBOL_POINTERS
&&
558 SectionType
!= MachO::S_THREAD_LOCAL_VARIABLE_POINTERS
&&
559 SectionType
!= MachO::S_SYMBOL_STUBS
)
560 return Error(Loc
, "indirect symbol not in a symbol pointer or stub "
564 if (getParser().parseIdentifier(Name
))
565 return TokError("expected identifier in .indirect_symbol directive");
567 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
569 // Assembler local symbols don't make any sense here. Complain loudly.
570 if (Sym
->isTemporary())
571 return TokError("non-local symbol required in directive");
573 if (!getStreamer().emitSymbolAttribute(Sym
, MCSA_IndirectSymbol
))
574 return TokError("unable to emit indirect symbol attribute for: " + Name
);
576 if (getLexer().isNot(AsmToken::EndOfStatement
))
577 return TokError("unexpected token in '.indirect_symbol' directive");
584 /// parseDirectiveDumpOrLoad
585 /// ::= ( .dump | .load ) "filename"
586 bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive
,
588 bool IsDump
= Directive
== ".dump";
589 if (getLexer().isNot(AsmToken::String
))
590 return TokError("expected string in '.dump' or '.load' directive");
594 if (getLexer().isNot(AsmToken::EndOfStatement
))
595 return TokError("unexpected token in '.dump' or '.load' directive");
599 // FIXME: If/when .dump and .load are implemented they will be done in the
600 // the assembly parser and not have any need for an MCStreamer API.
602 return Warning(IDLoc
, "ignoring directive .dump for now");
604 return Warning(IDLoc
, "ignoring directive .load for now");
607 /// ParseDirectiveLinkerOption
608 /// ::= .linker_option "string" ( , "string" )*
609 bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal
, SMLoc
) {
610 SmallVector
<std::string
, 4> Args
;
612 if (getLexer().isNot(AsmToken::String
))
613 return TokError("expected string in '" + Twine(IDVal
) + "' directive");
616 if (getParser().parseEscapedString(Data
))
619 Args
.push_back(Data
);
621 if (getLexer().is(AsmToken::EndOfStatement
))
624 if (getLexer().isNot(AsmToken::Comma
))
625 return TokError("unexpected token in '" + Twine(IDVal
) + "' directive");
629 getStreamer().emitLinkerOptions(Args
);
633 /// parseDirectiveLsym
634 /// ::= .lsym identifier , expression
635 bool DarwinAsmParser::parseDirectiveLsym(StringRef
, SMLoc
) {
637 if (getParser().parseIdentifier(Name
))
638 return TokError("expected identifier in directive");
640 // Handle the identifier as the key symbol.
641 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
643 if (getLexer().isNot(AsmToken::Comma
))
644 return TokError("unexpected token in '.lsym' directive");
648 if (getParser().parseExpression(Value
))
651 if (getLexer().isNot(AsmToken::EndOfStatement
))
652 return TokError("unexpected token in '.lsym' directive");
656 // We don't currently support this directive.
658 // FIXME: Diagnostic location!
660 return TokError("directive '.lsym' is unsupported");
663 /// parseDirectiveSection:
664 /// ::= .section identifier (',' identifier)*
665 bool DarwinAsmParser::parseDirectiveSection(StringRef
, SMLoc
) {
666 SMLoc Loc
= getLexer().getLoc();
668 StringRef SectionName
;
669 if (getParser().parseIdentifier(SectionName
))
670 return Error(Loc
, "expected identifier after '.section' directive");
672 // Verify there is a following comma.
673 if (!getLexer().is(AsmToken::Comma
))
674 return TokError("unexpected token in '.section' directive");
676 std::string SectionSpec
= std::string(SectionName
);
679 // Add all the tokens until the end of the line, ParseSectionSpecifier will
681 StringRef EOL
= getLexer().LexUntilEndOfStatement();
682 SectionSpec
.append(EOL
.begin(), EOL
.end());
685 if (getLexer().isNot(AsmToken::EndOfStatement
))
686 return TokError("unexpected token in '.section' directive");
689 StringRef Segment
, Section
;
693 if (class Error E
= MCSectionMachO::ParseSectionSpecifier(
694 SectionSpec
, Segment
, Section
, TAA
, TAAParsed
, StubSize
))
695 return Error(Loc
, toString(std::move(E
)));
697 // Issue a warning if the target is not powerpc and Section is a *coal* section.
698 Triple TT
= getParser().getContext().getTargetTriple();
699 Triple::ArchType ArchTy
= TT
.getArch();
701 if (ArchTy
!= Triple::ppc
&& ArchTy
!= Triple::ppc64
) {
702 StringRef NonCoalSection
= StringSwitch
<StringRef
>(Section
)
703 .Case("__textcoal_nt", "__text")
704 .Case("__const_coal", "__const")
705 .Case("__datacoal_nt", "__data")
708 if (!Section
.equals(NonCoalSection
)) {
709 StringRef
SectionVal(Loc
.getPointer());
710 size_t B
= SectionVal
.find(',') + 1, E
= SectionVal
.find(',', B
);
711 SMLoc BLoc
= SMLoc::getFromPointer(SectionVal
.data() + B
);
712 SMLoc ELoc
= SMLoc::getFromPointer(SectionVal
.data() + E
);
713 getParser().Warning(Loc
, "section \"" + Section
+ "\" is deprecated",
714 SMRange(BLoc
, ELoc
));
715 getParser().Note(Loc
, "change section name to \"" + NonCoalSection
+
716 "\"", SMRange(BLoc
, ELoc
));
720 // FIXME: Arch specific.
721 bool isText
= Segment
== "__TEXT"; // FIXME: Hack.
722 getStreamer().switchSection(getContext().getMachOSection(
723 Segment
, Section
, TAA
, StubSize
,
724 isText
? SectionKind::getText() : SectionKind::getData()));
728 /// ParseDirectivePushSection:
729 /// ::= .pushsection identifier (',' identifier)*
730 bool DarwinAsmParser::parseDirectivePushSection(StringRef S
, SMLoc Loc
) {
731 getStreamer().pushSection();
733 if (parseDirectiveSection(S
, Loc
)) {
734 getStreamer().popSection();
741 /// ParseDirectivePopSection:
743 bool DarwinAsmParser::parseDirectivePopSection(StringRef
, SMLoc
) {
744 if (!getStreamer().popSection())
745 return TokError(".popsection without corresponding .pushsection");
749 /// ParseDirectivePrevious:
751 bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName
, SMLoc
) {
752 MCSectionSubPair PreviousSection
= getStreamer().getPreviousSection();
753 if (!PreviousSection
.first
)
754 return TokError(".previous without corresponding .section");
755 getStreamer().switchSection(PreviousSection
.first
, PreviousSection
.second
);
759 /// ParseDirectiveSecureLogUnique
760 /// ::= .secure_log_unique ... message ...
761 bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef
, SMLoc IDLoc
) {
762 StringRef LogMessage
= getParser().parseStringToEndOfStatement();
763 if (getLexer().isNot(AsmToken::EndOfStatement
))
764 return TokError("unexpected token in '.secure_log_unique' directive");
766 if (getContext().getSecureLogUsed())
767 return Error(IDLoc
, ".secure_log_unique specified multiple times");
769 // Get the secure log path.
770 StringRef SecureLogFile
= getContext().getSecureLogFile();
771 if (SecureLogFile
.empty())
772 return Error(IDLoc
, ".secure_log_unique used but AS_SECURE_LOG_FILE "
773 "environment variable unset.");
775 // Open the secure log file if we haven't already.
776 raw_fd_ostream
*OS
= getContext().getSecureLog();
779 auto NewOS
= std::make_unique
<raw_fd_ostream
>(
780 SecureLogFile
, EC
, sys::fs::OF_Append
| sys::fs::OF_TextWithCRLF
);
782 return Error(IDLoc
, Twine("can't open secure log file: ") +
783 SecureLogFile
+ " (" + EC
.message() + ")");
785 getContext().setSecureLog(std::move(NewOS
));
788 // Write the message.
789 unsigned CurBuf
= getSourceManager().FindBufferContainingLoc(IDLoc
);
790 *OS
<< getSourceManager().getBufferInfo(CurBuf
).Buffer
->getBufferIdentifier()
791 << ":" << getSourceManager().FindLineNumber(IDLoc
, CurBuf
) << ":"
792 << LogMessage
+ "\n";
794 getContext().setSecureLogUsed(true);
799 /// ParseDirectiveSecureLogReset
800 /// ::= .secure_log_reset
801 bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef
, SMLoc IDLoc
) {
802 if (getLexer().isNot(AsmToken::EndOfStatement
))
803 return TokError("unexpected token in '.secure_log_reset' directive");
807 getContext().setSecureLogUsed(false);
812 /// parseDirectiveSubsectionsViaSymbols
813 /// ::= .subsections_via_symbols
814 bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef
, SMLoc
) {
815 if (getLexer().isNot(AsmToken::EndOfStatement
))
816 return TokError("unexpected token in '.subsections_via_symbols' directive");
820 getStreamer().emitAssemblerFlag(MCAF_SubsectionsViaSymbols
);
825 /// ParseDirectiveTBSS
826 /// ::= .tbss identifier, size, align
827 bool DarwinAsmParser::parseDirectiveTBSS(StringRef
, SMLoc
) {
828 SMLoc IDLoc
= getLexer().getLoc();
830 if (getParser().parseIdentifier(Name
))
831 return TokError("expected identifier in directive");
833 // Handle the identifier as the key symbol.
834 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
836 if (getLexer().isNot(AsmToken::Comma
))
837 return TokError("unexpected token in directive");
841 SMLoc SizeLoc
= getLexer().getLoc();
842 if (getParser().parseAbsoluteExpression(Size
))
845 int64_t Pow2Alignment
= 0;
846 SMLoc Pow2AlignmentLoc
;
847 if (getLexer().is(AsmToken::Comma
)) {
849 Pow2AlignmentLoc
= getLexer().getLoc();
850 if (getParser().parseAbsoluteExpression(Pow2Alignment
))
854 if (getLexer().isNot(AsmToken::EndOfStatement
))
855 return TokError("unexpected token in '.tbss' directive");
860 return Error(SizeLoc
, "invalid '.tbss' directive size, can't be less than"
863 // FIXME: Diagnose overflow.
864 if (Pow2Alignment
< 0)
865 return Error(Pow2AlignmentLoc
, "invalid '.tbss' alignment, can't be less"
868 if (!Sym
->isUndefined())
869 return Error(IDLoc
, "invalid symbol redefinition");
871 getStreamer().emitTBSSSymbol(
872 getContext().getMachOSection("__DATA", "__thread_bss",
873 MachO::S_THREAD_LOCAL_ZEROFILL
, 0,
874 SectionKind::getThreadBSS()),
875 Sym
, Size
, Align(1ULL << Pow2Alignment
));
880 /// ParseDirectiveZerofill
881 /// ::= .zerofill segname , sectname [, identifier , size_expression [
882 /// , align_expression ]]
883 bool DarwinAsmParser::parseDirectiveZerofill(StringRef
, SMLoc
) {
885 if (getParser().parseIdentifier(Segment
))
886 return TokError("expected segment name after '.zerofill' directive");
888 if (getLexer().isNot(AsmToken::Comma
))
889 return TokError("unexpected token in directive");
893 SMLoc SectionLoc
= getLexer().getLoc();
894 if (getParser().parseIdentifier(Section
))
895 return TokError("expected section name after comma in '.zerofill' "
898 // If this is the end of the line all that was wanted was to create the
899 // the section but with no symbol.
900 if (getLexer().is(AsmToken::EndOfStatement
)) {
901 // Create the zerofill section but no symbol
902 getStreamer().emitZerofill(
903 getContext().getMachOSection(Segment
, Section
, MachO::S_ZEROFILL
, 0,
904 SectionKind::getBSS()),
905 /*Symbol=*/nullptr, /*Size=*/0, Align(1), SectionLoc
);
909 if (getLexer().isNot(AsmToken::Comma
))
910 return TokError("unexpected token in directive");
913 SMLoc IDLoc
= getLexer().getLoc();
915 if (getParser().parseIdentifier(IDStr
))
916 return TokError("expected identifier in directive");
918 // handle the identifier as the key symbol.
919 MCSymbol
*Sym
= getContext().getOrCreateSymbol(IDStr
);
921 if (getLexer().isNot(AsmToken::Comma
))
922 return TokError("unexpected token in directive");
926 SMLoc SizeLoc
= getLexer().getLoc();
927 if (getParser().parseAbsoluteExpression(Size
))
930 int64_t Pow2Alignment
= 0;
931 SMLoc Pow2AlignmentLoc
;
932 if (getLexer().is(AsmToken::Comma
)) {
934 Pow2AlignmentLoc
= getLexer().getLoc();
935 if (getParser().parseAbsoluteExpression(Pow2Alignment
))
939 if (getLexer().isNot(AsmToken::EndOfStatement
))
940 return TokError("unexpected token in '.zerofill' directive");
945 return Error(SizeLoc
, "invalid '.zerofill' directive size, can't be less "
948 // NOTE: The alignment in the directive is a power of 2 value, the assembler
949 // may internally end up wanting an alignment in bytes.
950 // FIXME: Diagnose overflow.
951 if (Pow2Alignment
< 0)
952 return Error(Pow2AlignmentLoc
, "invalid '.zerofill' directive alignment, "
953 "can't be less than zero");
955 if (!Sym
->isUndefined())
956 return Error(IDLoc
, "invalid symbol redefinition");
958 // Create the zerofill Symbol with Size and Pow2Alignment
960 // FIXME: Arch specific.
961 getStreamer().emitZerofill(
962 getContext().getMachOSection(Segment
, Section
, MachO::S_ZEROFILL
, 0,
963 SectionKind::getBSS()),
964 Sym
, Size
, Align(1ULL << Pow2Alignment
), SectionLoc
);
969 /// ParseDirectiveDataRegion
970 /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
971 bool DarwinAsmParser::parseDirectiveDataRegion(StringRef
, SMLoc
) {
972 if (getLexer().is(AsmToken::EndOfStatement
)) {
974 getStreamer().emitDataRegion(MCDR_DataRegion
);
977 StringRef RegionType
;
978 SMLoc Loc
= getParser().getTok().getLoc();
979 if (getParser().parseIdentifier(RegionType
))
980 return TokError("expected region type after '.data_region' directive");
981 int Kind
= StringSwitch
<int>(RegionType
)
982 .Case("jt8", MCDR_DataRegionJT8
)
983 .Case("jt16", MCDR_DataRegionJT16
)
984 .Case("jt32", MCDR_DataRegionJT32
)
987 return Error(Loc
, "unknown region type in '.data_region' directive");
990 getStreamer().emitDataRegion((MCDataRegionType
)Kind
);
994 /// ParseDirectiveDataRegionEnd
995 /// ::= .end_data_region
996 bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef
, SMLoc
) {
997 if (getLexer().isNot(AsmToken::EndOfStatement
))
998 return TokError("unexpected token in '.end_data_region' directive");
1001 getStreamer().emitDataRegion(MCDR_DataRegionEnd
);
1005 static bool isSDKVersionToken(const AsmToken
&Tok
) {
1006 return Tok
.is(AsmToken::Identifier
) && Tok
.getIdentifier() == "sdk_version";
1009 /// parseMajorMinorVersionComponent ::= major, minor
1010 bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major
,
1012 const char *VersionName
) {
1013 // Get the major version number.
1014 if (getLexer().isNot(AsmToken::Integer
))
1015 return TokError(Twine("invalid ") + VersionName
+
1016 " major version number, integer expected");
1017 int64_t MajorVal
= getLexer().getTok().getIntVal();
1018 if (MajorVal
> 65535 || MajorVal
<= 0)
1019 return TokError(Twine("invalid ") + VersionName
+ " major version number");
1020 *Major
= (unsigned)MajorVal
;
1022 if (getLexer().isNot(AsmToken::Comma
))
1023 return TokError(Twine(VersionName
) +
1024 " minor version number required, comma expected");
1026 // Get the minor version number.
1027 if (getLexer().isNot(AsmToken::Integer
))
1028 return TokError(Twine("invalid ") + VersionName
+
1029 " minor version number, integer expected");
1030 int64_t MinorVal
= getLexer().getTok().getIntVal();
1031 if (MinorVal
> 255 || MinorVal
< 0)
1032 return TokError(Twine("invalid ") + VersionName
+ " minor version number");
1038 /// parseOptionalTrailingVersionComponent ::= , version_number
1039 bool DarwinAsmParser::parseOptionalTrailingVersionComponent(
1040 unsigned *Component
, const char *ComponentName
) {
1041 assert(getLexer().is(AsmToken::Comma
) && "comma expected");
1043 if (getLexer().isNot(AsmToken::Integer
))
1044 return TokError(Twine("invalid ") + ComponentName
+
1045 " version number, integer expected");
1046 int64_t Val
= getLexer().getTok().getIntVal();
1047 if (Val
> 255 || Val
< 0)
1048 return TokError(Twine("invalid ") + ComponentName
+ " version number");
1054 /// parseVersion ::= parseMajorMinorVersionComponent
1055 /// parseOptionalTrailingVersionComponent
1056 bool DarwinAsmParser::parseVersion(unsigned *Major
, unsigned *Minor
,
1058 if (parseMajorMinorVersionComponent(Major
, Minor
, "OS"))
1061 // Get the update level, if specified
1063 if (getLexer().is(AsmToken::EndOfStatement
) ||
1064 isSDKVersionToken(getLexer().getTok()))
1066 if (getLexer().isNot(AsmToken::Comma
))
1067 return TokError("invalid OS update specifier, comma expected");
1068 if (parseOptionalTrailingVersionComponent(Update
, "OS update"))
1073 bool DarwinAsmParser::parseSDKVersion(VersionTuple
&SDKVersion
) {
1074 assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version");
1076 unsigned Major
, Minor
;
1077 if (parseMajorMinorVersionComponent(&Major
, &Minor
, "SDK"))
1079 SDKVersion
= VersionTuple(Major
, Minor
);
1081 // Get the subminor version, if specified.
1082 if (getLexer().is(AsmToken::Comma
)) {
1084 if (parseOptionalTrailingVersionComponent(&Subminor
, "SDK subminor"))
1086 SDKVersion
= VersionTuple(Major
, Minor
, Subminor
);
1091 void DarwinAsmParser::checkVersion(StringRef Directive
, StringRef Arg
,
1092 SMLoc Loc
, Triple::OSType ExpectedOS
) {
1093 const Triple
&Target
= getContext().getTargetTriple();
1094 if (Target
.getOS() != ExpectedOS
)
1095 Warning(Loc
, Twine(Directive
) +
1096 (Arg
.empty() ? Twine() : Twine(' ') + Arg
) +
1097 " used while targeting " + Target
.getOSName());
1099 if (LastVersionDirective
.isValid()) {
1100 Warning(Loc
, "overriding previous version directive");
1101 Note(LastVersionDirective
, "previous definition is here");
1103 LastVersionDirective
= Loc
;
1106 static Triple::OSType
getOSTypeFromMCVM(MCVersionMinType Type
) {
1108 case MCVM_WatchOSVersionMin
: return Triple::WatchOS
;
1109 case MCVM_TvOSVersionMin
: return Triple::TvOS
;
1110 case MCVM_IOSVersionMin
: return Triple::IOS
;
1111 case MCVM_OSXVersionMin
: return Triple::MacOSX
;
1113 llvm_unreachable("Invalid mc version min type");
1117 /// ::= .ios_version_min parseVersion parseSDKVersion
1118 /// | .macosx_version_min parseVersion parseSDKVersion
1119 /// | .tvos_version_min parseVersion parseSDKVersion
1120 /// | .watchos_version_min parseVersion parseSDKVersion
1121 bool DarwinAsmParser::parseVersionMin(StringRef Directive
, SMLoc Loc
,
1122 MCVersionMinType Type
) {
1126 if (parseVersion(&Major
, &Minor
, &Update
))
1129 VersionTuple SDKVersion
;
1130 if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion
))
1134 return addErrorSuffix(Twine(" in '") + Directive
+ "' directive");
1136 Triple::OSType ExpectedOS
= getOSTypeFromMCVM(Type
);
1137 checkVersion(Directive
, StringRef(), Loc
, ExpectedOS
);
1138 getStreamer().emitVersionMin(Type
, Major
, Minor
, Update
, SDKVersion
);
1142 static Triple::OSType
getOSTypeFromPlatform(MachO::PlatformType Type
) {
1144 case MachO::PLATFORM_UNKNOWN
: /* silence warning */
1146 case MachO::PLATFORM_MACOS
: return Triple::MacOSX
;
1147 case MachO::PLATFORM_IOS
: return Triple::IOS
;
1148 case MachO::PLATFORM_TVOS
: return Triple::TvOS
;
1149 case MachO::PLATFORM_WATCHOS
: return Triple::WatchOS
;
1150 case MachO::PLATFORM_XROS
: return Triple::XROS
;
1151 case MachO::PLATFORM_BRIDGEOS
: /* silence warning */ break;
1152 case MachO::PLATFORM_DRIVERKIT
:
1153 return Triple::DriverKit
;
1154 case MachO::PLATFORM_MACCATALYST
: return Triple::IOS
;
1155 case MachO::PLATFORM_IOSSIMULATOR
: /* silence warning */ break;
1156 case MachO::PLATFORM_TVOSSIMULATOR
: /* silence warning */ break;
1157 case MachO::PLATFORM_WATCHOSSIMULATOR
: /* silence warning */ break;
1158 case MachO::PLATFORM_XROS_SIMULATOR
: /* silence warning */ break;
1160 llvm_unreachable("Invalid mach-o platform type");
1163 /// parseBuildVersion
1164 /// ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion
1165 bool DarwinAsmParser::parseBuildVersion(StringRef Directive
, SMLoc Loc
) {
1166 StringRef PlatformName
;
1167 SMLoc PlatformLoc
= getTok().getLoc();
1168 if (getParser().parseIdentifier(PlatformName
))
1169 return TokError("platform name expected");
1171 unsigned Platform
= StringSwitch
<unsigned>(PlatformName
)
1172 #define PLATFORM(platform, id, name, build_name, target, tapi_target, \
1174 .Case(#build_name, MachO::PLATFORM_##platform)
1175 #include "llvm/BinaryFormat/MachO.def"
1176 .Default(MachO::PLATFORM_UNKNOWN
);
1178 if (Platform
== MachO::PLATFORM_UNKNOWN
)
1179 return Error(PlatformLoc
, "unknown platform name");
1181 if (getLexer().isNot(AsmToken::Comma
))
1182 return TokError("version number required, comma expected");
1188 if (parseVersion(&Major
, &Minor
, &Update
))
1191 VersionTuple SDKVersion
;
1192 if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion
))
1196 return addErrorSuffix(" in '.build_version' directive");
1198 Triple::OSType ExpectedOS
1199 = getOSTypeFromPlatform((MachO::PlatformType
)Platform
);
1200 checkVersion(Directive
, PlatformName
, Loc
, ExpectedOS
);
1201 getStreamer().emitBuildVersion(Platform
, Major
, Minor
, Update
, SDKVersion
);
1205 /// parseDirectiveCGProfile
1206 /// ::= .cg_profile from, to, count
1207 bool DarwinAsmParser::parseDirectiveCGProfile(StringRef S
, SMLoc Loc
) {
1208 return MCAsmParserExtension::ParseDirectiveCGProfile(S
, Loc
);
1213 MCAsmParserExtension
*createDarwinAsmParser() {
1214 return new DarwinAsmParser
;
1217 } // end llvm namespace