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/STLExtras.h"
10 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/ADT/Triple.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/BinaryFormat/MachO.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCDirectives.h"
18 #include "llvm/MC/MCObjectFileInfo.h"
19 #include "llvm/MC/MCParser/MCAsmLexer.h"
20 #include "llvm/MC/MCParser/MCAsmParser.h"
21 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
22 #include "llvm/MC/MCSectionMachO.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/MC/SectionKind.h"
26 #include "llvm/Support/FileSystem.h"
27 #include "llvm/Support/MemoryBuffer.h"
28 #include "llvm/Support/SMLoc.h"
29 #include "llvm/Support/SourceMgr.h"
30 #include "llvm/Support/raw_ostream.h"
35 #include <system_error>
42 /// Implementation of directive handling which is shared across all
44 class DarwinAsmParser
: public MCAsmParserExtension
{
45 template<bool (DarwinAsmParser::*HandlerMethod
)(StringRef
, SMLoc
)>
46 void addDirectiveHandler(StringRef Directive
) {
47 MCAsmParser::ExtensionDirectiveHandler Handler
= std::make_pair(
48 this, HandleDirective
<DarwinAsmParser
, HandlerMethod
>);
49 getParser().addDirectiveHandler(Directive
, Handler
);
52 bool parseSectionSwitch(StringRef Segment
, StringRef Section
,
53 unsigned TAA
= 0, unsigned ImplicitAlign
= 0,
54 unsigned StubSize
= 0);
56 SMLoc LastVersionDirective
;
59 DarwinAsmParser() = default;
61 void Initialize(MCAsmParser
&Parser
) override
{
62 // Call the base implementation.
63 this->MCAsmParserExtension::Initialize(Parser
);
65 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveAltEntry
>(".alt_entry");
66 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveDesc
>(".desc");
67 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveIndirectSymbol
>(
69 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveLsym
>(".lsym");
70 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols
>(
71 ".subsections_via_symbols");
72 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveDumpOrLoad
>(".dump");
73 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveDumpOrLoad
>(".load");
74 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveSection
>(".section");
75 addDirectiveHandler
<&DarwinAsmParser::parseDirectivePushSection
>(
77 addDirectiveHandler
<&DarwinAsmParser::parseDirectivePopSection
>(
79 addDirectiveHandler
<&DarwinAsmParser::parseDirectivePrevious
>(".previous");
80 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveSecureLogUnique
>(
81 ".secure_log_unique");
82 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveSecureLogReset
>(
84 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveTBSS
>(".tbss");
85 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveZerofill
>(".zerofill");
87 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveDataRegion
>(
89 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveDataRegionEnd
>(
92 // Special section directives.
93 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveBss
>(".bss");
94 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveConst
>(".const");
95 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveConstData
>(
97 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveConstructor
>(
99 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveCString
>(
101 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveData
>(".data");
102 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveDestructor
>(
104 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveDyld
>(".dyld");
105 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0
>(
107 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1
>(
110 &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers
>(
111 ".lazy_symbol_pointer");
112 addDirectiveHandler
<&DarwinAsmParser::parseDirectiveLinkerOption
>(
114 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveLiteral16
>(
116 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveLiteral4
>(
118 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveLiteral8
>(
120 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveModInitFunc
>(
122 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveModTermFunc
>(
125 &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers
>(
126 ".non_lazy_symbol_pointer");
128 &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers
>(
129 ".thread_local_variable_pointer");
130 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth
>(
131 ".objc_cat_cls_meth");
132 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth
>(
133 ".objc_cat_inst_meth");
134 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCCategory
>(
136 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCClass
>(
138 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCClassNames
>(
139 ".objc_class_names");
140 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCClassVars
>(
142 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth
>(
144 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs
>(
146 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth
>(
149 &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars
>(
150 ".objc_instance_vars");
151 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs
>(
152 ".objc_message_refs");
153 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass
>(
156 &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames
>(
157 ".objc_meth_var_names");
159 &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes
>(
160 ".objc_meth_var_types");
161 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo
>(
162 ".objc_module_info");
163 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCProtocol
>(
166 &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs
>(
167 ".objc_selector_strs");
169 &DarwinAsmParser::parseSectionDirectiveObjCStringObject
>(
170 ".objc_string_object");
171 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveObjCSymbols
>(
173 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectivePICSymbolStub
>(
175 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveStaticConst
>(
177 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveStaticData
>(
179 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveSymbolStub
>(
181 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveTData
>(".tdata");
182 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveText
>(".text");
183 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc
>(
184 ".thread_init_func");
185 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveTLV
>(".tlv");
187 addDirectiveHandler
<&DarwinAsmParser::parseSectionDirectiveIdent
>(".ident");
188 addDirectiveHandler
<&DarwinAsmParser::parseWatchOSVersionMin
>(
189 ".watchos_version_min");
190 addDirectiveHandler
<&DarwinAsmParser::parseTvOSVersionMin
>(
191 ".tvos_version_min");
192 addDirectiveHandler
<&DarwinAsmParser::parseIOSVersionMin
>(
194 addDirectiveHandler
<&DarwinAsmParser::parseMacOSXVersionMin
>(
195 ".macosx_version_min");
196 addDirectiveHandler
<&DarwinAsmParser::parseBuildVersion
>(".build_version");
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
);
471 } // end anonymous namespace
473 bool DarwinAsmParser::parseSectionSwitch(StringRef Segment
, StringRef Section
,
474 unsigned TAA
, unsigned Align
,
476 if (getLexer().isNot(AsmToken::EndOfStatement
))
477 return TokError("unexpected token in section switching directive");
480 // FIXME: Arch specific.
481 bool isText
= TAA
& MachO::S_ATTR_PURE_INSTRUCTIONS
;
482 getStreamer().SwitchSection(getContext().getMachOSection(
483 Segment
, Section
, TAA
, StubSize
,
484 isText
? SectionKind::getText() : SectionKind::getData()));
486 // Set the implicit alignment, if any.
488 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
489 // alignment on the section (e.g., if one manually inserts bytes into the
490 // section, then just issuing the section switch directive will not realign
491 // the section. However, this is arguably more reasonable behavior, and there
492 // is no good reason for someone to intentionally emit incorrectly sized
493 // values into the implicitly aligned sections.
495 getStreamer().EmitValueToAlignment(Align
);
500 /// parseDirectiveAltEntry
501 /// ::= .alt_entry identifier
502 bool DarwinAsmParser::parseDirectiveAltEntry(StringRef
, SMLoc
) {
504 if (getParser().parseIdentifier(Name
))
505 return TokError("expected identifier in directive");
508 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
510 if (Sym
->isDefined())
511 return TokError(".alt_entry must preceed symbol definition");
513 if (!getStreamer().EmitSymbolAttribute(Sym
, MCSA_AltEntry
))
514 return TokError("unable to emit symbol attribute");
520 /// parseDirectiveDesc
521 /// ::= .desc identifier , expression
522 bool DarwinAsmParser::parseDirectiveDesc(StringRef
, SMLoc
) {
524 if (getParser().parseIdentifier(Name
))
525 return TokError("expected identifier in directive");
527 // Handle the identifier as the key symbol.
528 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
530 if (getLexer().isNot(AsmToken::Comma
))
531 return TokError("unexpected token in '.desc' directive");
535 if (getParser().parseAbsoluteExpression(DescValue
))
538 if (getLexer().isNot(AsmToken::EndOfStatement
))
539 return TokError("unexpected token in '.desc' directive");
543 // Set the n_desc field of this Symbol to this DescValue
544 getStreamer().EmitSymbolDesc(Sym
, DescValue
);
549 /// parseDirectiveIndirectSymbol
550 /// ::= .indirect_symbol identifier
551 bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef
, SMLoc Loc
) {
552 const MCSectionMachO
*Current
= static_cast<const MCSectionMachO
*>(
553 getStreamer().getCurrentSectionOnly());
554 MachO::SectionType SectionType
= Current
->getType();
555 if (SectionType
!= MachO::S_NON_LAZY_SYMBOL_POINTERS
&&
556 SectionType
!= MachO::S_LAZY_SYMBOL_POINTERS
&&
557 SectionType
!= MachO::S_THREAD_LOCAL_VARIABLE_POINTERS
&&
558 SectionType
!= MachO::S_SYMBOL_STUBS
)
559 return Error(Loc
, "indirect symbol not in a symbol pointer or stub "
563 if (getParser().parseIdentifier(Name
))
564 return TokError("expected identifier in .indirect_symbol directive");
566 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
568 // Assembler local symbols don't make any sense here. Complain loudly.
569 if (Sym
->isTemporary())
570 return TokError("non-local symbol required in directive");
572 if (!getStreamer().EmitSymbolAttribute(Sym
, MCSA_IndirectSymbol
))
573 return TokError("unable to emit indirect symbol attribute for: " + Name
);
575 if (getLexer().isNot(AsmToken::EndOfStatement
))
576 return TokError("unexpected token in '.indirect_symbol' directive");
583 /// parseDirectiveDumpOrLoad
584 /// ::= ( .dump | .load ) "filename"
585 bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive
,
587 bool IsDump
= Directive
== ".dump";
588 if (getLexer().isNot(AsmToken::String
))
589 return TokError("expected string in '.dump' or '.load' directive");
593 if (getLexer().isNot(AsmToken::EndOfStatement
))
594 return TokError("unexpected token in '.dump' or '.load' directive");
598 // FIXME: If/when .dump and .load are implemented they will be done in the
599 // the assembly parser and not have any need for an MCStreamer API.
601 return Warning(IDLoc
, "ignoring directive .dump for now");
603 return Warning(IDLoc
, "ignoring directive .load for now");
606 /// ParseDirectiveLinkerOption
607 /// ::= .linker_option "string" ( , "string" )*
608 bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal
, SMLoc
) {
609 SmallVector
<std::string
, 4> Args
;
611 if (getLexer().isNot(AsmToken::String
))
612 return TokError("expected string in '" + Twine(IDVal
) + "' directive");
615 if (getParser().parseEscapedString(Data
))
618 Args
.push_back(Data
);
620 if (getLexer().is(AsmToken::EndOfStatement
))
623 if (getLexer().isNot(AsmToken::Comma
))
624 return TokError("unexpected token in '" + Twine(IDVal
) + "' directive");
628 getStreamer().EmitLinkerOptions(Args
);
632 /// parseDirectiveLsym
633 /// ::= .lsym identifier , expression
634 bool DarwinAsmParser::parseDirectiveLsym(StringRef
, SMLoc
) {
636 if (getParser().parseIdentifier(Name
))
637 return TokError("expected identifier in directive");
639 // Handle the identifier as the key symbol.
640 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
642 if (getLexer().isNot(AsmToken::Comma
))
643 return TokError("unexpected token in '.lsym' directive");
647 if (getParser().parseExpression(Value
))
650 if (getLexer().isNot(AsmToken::EndOfStatement
))
651 return TokError("unexpected token in '.lsym' directive");
655 // We don't currently support this directive.
657 // FIXME: Diagnostic location!
659 return TokError("directive '.lsym' is unsupported");
662 /// parseDirectiveSection:
663 /// ::= .section identifier (',' identifier)*
664 bool DarwinAsmParser::parseDirectiveSection(StringRef
, SMLoc
) {
665 SMLoc Loc
= getLexer().getLoc();
667 StringRef SectionName
;
668 if (getParser().parseIdentifier(SectionName
))
669 return Error(Loc
, "expected identifier after '.section' directive");
671 // Verify there is a following comma.
672 if (!getLexer().is(AsmToken::Comma
))
673 return TokError("unexpected token in '.section' directive");
675 std::string SectionSpec
= SectionName
;
678 // Add all the tokens until the end of the line, ParseSectionSpecifier will
680 StringRef EOL
= getLexer().LexUntilEndOfStatement();
681 SectionSpec
.append(EOL
.begin(), EOL
.end());
684 if (getLexer().isNot(AsmToken::EndOfStatement
))
685 return TokError("unexpected token in '.section' directive");
688 StringRef Segment
, Section
;
692 std::string ErrorStr
=
693 MCSectionMachO::ParseSectionSpecifier(SectionSpec
, Segment
, Section
,
694 TAA
, TAAParsed
, StubSize
);
696 if (!ErrorStr
.empty())
697 return Error(Loc
, ErrorStr
);
699 // Issue a warning if the target is not powerpc and Section is a *coal* section.
700 Triple TT
= getParser().getContext().getObjectFileInfo()->getTargetTriple();
701 Triple::ArchType ArchTy
= TT
.getArch();
703 if (ArchTy
!= Triple::ppc
&& ArchTy
!= Triple::ppc64
) {
704 StringRef NonCoalSection
= StringSwitch
<StringRef
>(Section
)
705 .Case("__textcoal_nt", "__text")
706 .Case("__const_coal", "__const")
707 .Case("__datacoal_nt", "__data")
710 if (!Section
.equals(NonCoalSection
)) {
711 StringRef
SectionVal(Loc
.getPointer());
712 size_t B
= SectionVal
.find(',') + 1, E
= SectionVal
.find(',', B
);
713 SMLoc BLoc
= SMLoc::getFromPointer(SectionVal
.data() + B
);
714 SMLoc ELoc
= SMLoc::getFromPointer(SectionVal
.data() + E
);
715 getParser().Warning(Loc
, "section \"" + Section
+ "\" is deprecated",
716 SMRange(BLoc
, ELoc
));
717 getParser().Note(Loc
, "change section name to \"" + NonCoalSection
+
718 "\"", SMRange(BLoc
, ELoc
));
722 // FIXME: Arch specific.
723 bool isText
= Segment
== "__TEXT"; // FIXME: Hack.
724 getStreamer().SwitchSection(getContext().getMachOSection(
725 Segment
, Section
, TAA
, StubSize
,
726 isText
? SectionKind::getText() : SectionKind::getData()));
730 /// ParseDirectivePushSection:
731 /// ::= .pushsection identifier (',' identifier)*
732 bool DarwinAsmParser::parseDirectivePushSection(StringRef S
, SMLoc Loc
) {
733 getStreamer().PushSection();
735 if (parseDirectiveSection(S
, Loc
)) {
736 getStreamer().PopSection();
743 /// ParseDirectivePopSection:
745 bool DarwinAsmParser::parseDirectivePopSection(StringRef
, SMLoc
) {
746 if (!getStreamer().PopSection())
747 return TokError(".popsection without corresponding .pushsection");
751 /// ParseDirectivePrevious:
753 bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName
, SMLoc
) {
754 MCSectionSubPair PreviousSection
= getStreamer().getPreviousSection();
755 if (!PreviousSection
.first
)
756 return TokError(".previous without corresponding .section");
757 getStreamer().SwitchSection(PreviousSection
.first
, PreviousSection
.second
);
761 /// ParseDirectiveSecureLogUnique
762 /// ::= .secure_log_unique ... message ...
763 bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef
, SMLoc IDLoc
) {
764 StringRef LogMessage
= getParser().parseStringToEndOfStatement();
765 if (getLexer().isNot(AsmToken::EndOfStatement
))
766 return TokError("unexpected token in '.secure_log_unique' directive");
768 if (getContext().getSecureLogUsed())
769 return Error(IDLoc
, ".secure_log_unique specified multiple times");
771 // Get the secure log path.
772 const char *SecureLogFile
= getContext().getSecureLogFile();
774 return Error(IDLoc
, ".secure_log_unique used but AS_SECURE_LOG_FILE "
775 "environment variable unset.");
777 // Open the secure log file if we haven't already.
778 raw_fd_ostream
*OS
= getContext().getSecureLog();
781 auto NewOS
= std::make_unique
<raw_fd_ostream
>(
782 StringRef(SecureLogFile
), EC
, sys::fs::OF_Append
| sys::fs::OF_Text
);
784 return Error(IDLoc
, Twine("can't open secure log file: ") +
785 SecureLogFile
+ " (" + EC
.message() + ")");
787 getContext().setSecureLog(std::move(NewOS
));
790 // Write the message.
791 unsigned CurBuf
= getSourceManager().FindBufferContainingLoc(IDLoc
);
792 *OS
<< getSourceManager().getBufferInfo(CurBuf
).Buffer
->getBufferIdentifier()
793 << ":" << getSourceManager().FindLineNumber(IDLoc
, CurBuf
) << ":"
794 << LogMessage
+ "\n";
796 getContext().setSecureLogUsed(true);
801 /// ParseDirectiveSecureLogReset
802 /// ::= .secure_log_reset
803 bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef
, SMLoc IDLoc
) {
804 if (getLexer().isNot(AsmToken::EndOfStatement
))
805 return TokError("unexpected token in '.secure_log_reset' directive");
809 getContext().setSecureLogUsed(false);
814 /// parseDirectiveSubsectionsViaSymbols
815 /// ::= .subsections_via_symbols
816 bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef
, SMLoc
) {
817 if (getLexer().isNot(AsmToken::EndOfStatement
))
818 return TokError("unexpected token in '.subsections_via_symbols' directive");
822 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols
);
827 /// ParseDirectiveTBSS
828 /// ::= .tbss identifier, size, align
829 bool DarwinAsmParser::parseDirectiveTBSS(StringRef
, SMLoc
) {
830 SMLoc IDLoc
= getLexer().getLoc();
832 if (getParser().parseIdentifier(Name
))
833 return TokError("expected identifier in directive");
835 // Handle the identifier as the key symbol.
836 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
838 if (getLexer().isNot(AsmToken::Comma
))
839 return TokError("unexpected token in directive");
843 SMLoc SizeLoc
= getLexer().getLoc();
844 if (getParser().parseAbsoluteExpression(Size
))
847 int64_t Pow2Alignment
= 0;
848 SMLoc Pow2AlignmentLoc
;
849 if (getLexer().is(AsmToken::Comma
)) {
851 Pow2AlignmentLoc
= getLexer().getLoc();
852 if (getParser().parseAbsoluteExpression(Pow2Alignment
))
856 if (getLexer().isNot(AsmToken::EndOfStatement
))
857 return TokError("unexpected token in '.tbss' directive");
862 return Error(SizeLoc
, "invalid '.tbss' directive size, can't be less than"
865 // FIXME: Diagnose overflow.
866 if (Pow2Alignment
< 0)
867 return Error(Pow2AlignmentLoc
, "invalid '.tbss' alignment, can't be less"
870 if (!Sym
->isUndefined())
871 return Error(IDLoc
, "invalid symbol redefinition");
873 getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
874 "__DATA", "__thread_bss",
875 MachO::S_THREAD_LOCAL_ZEROFILL
,
876 0, SectionKind::getThreadBSS()),
877 Sym
, Size
, 1 << Pow2Alignment
);
882 /// ParseDirectiveZerofill
883 /// ::= .zerofill segname , sectname [, identifier , size_expression [
884 /// , align_expression ]]
885 bool DarwinAsmParser::parseDirectiveZerofill(StringRef
, SMLoc
) {
887 if (getParser().parseIdentifier(Segment
))
888 return TokError("expected segment name after '.zerofill' directive");
890 if (getLexer().isNot(AsmToken::Comma
))
891 return TokError("unexpected token in directive");
895 SMLoc SectionLoc
= getLexer().getLoc();
896 if (getParser().parseIdentifier(Section
))
897 return TokError("expected section name after comma in '.zerofill' "
900 // If this is the end of the line all that was wanted was to create the
901 // the section but with no symbol.
902 if (getLexer().is(AsmToken::EndOfStatement
)) {
903 // Create the zerofill section but no symbol
904 getStreamer().EmitZerofill(
905 getContext().getMachOSection(Segment
, Section
, MachO::S_ZEROFILL
, 0,
906 SectionKind::getBSS()),
907 /*Symbol=*/nullptr, /*Size=*/0, /*ByteAlignment=*/0, SectionLoc
);
911 if (getLexer().isNot(AsmToken::Comma
))
912 return TokError("unexpected token in directive");
915 SMLoc IDLoc
= getLexer().getLoc();
917 if (getParser().parseIdentifier(IDStr
))
918 return TokError("expected identifier in directive");
920 // handle the identifier as the key symbol.
921 MCSymbol
*Sym
= getContext().getOrCreateSymbol(IDStr
);
923 if (getLexer().isNot(AsmToken::Comma
))
924 return TokError("unexpected token in directive");
928 SMLoc SizeLoc
= getLexer().getLoc();
929 if (getParser().parseAbsoluteExpression(Size
))
932 int64_t Pow2Alignment
= 0;
933 SMLoc Pow2AlignmentLoc
;
934 if (getLexer().is(AsmToken::Comma
)) {
936 Pow2AlignmentLoc
= getLexer().getLoc();
937 if (getParser().parseAbsoluteExpression(Pow2Alignment
))
941 if (getLexer().isNot(AsmToken::EndOfStatement
))
942 return TokError("unexpected token in '.zerofill' directive");
947 return Error(SizeLoc
, "invalid '.zerofill' directive size, can't be less "
950 // NOTE: The alignment in the directive is a power of 2 value, the assembler
951 // may internally end up wanting an alignment in bytes.
952 // FIXME: Diagnose overflow.
953 if (Pow2Alignment
< 0)
954 return Error(Pow2AlignmentLoc
, "invalid '.zerofill' directive alignment, "
955 "can't be less than zero");
957 if (!Sym
->isUndefined())
958 return Error(IDLoc
, "invalid symbol redefinition");
960 // Create the zerofill Symbol with Size and Pow2Alignment
962 // FIXME: Arch specific.
963 getStreamer().EmitZerofill(getContext().getMachOSection(
964 Segment
, Section
, MachO::S_ZEROFILL
,
965 0, SectionKind::getBSS()),
966 Sym
, Size
, 1 << Pow2Alignment
, SectionLoc
);
971 /// ParseDirectiveDataRegion
972 /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
973 bool DarwinAsmParser::parseDirectiveDataRegion(StringRef
, SMLoc
) {
974 if (getLexer().is(AsmToken::EndOfStatement
)) {
976 getStreamer().EmitDataRegion(MCDR_DataRegion
);
979 StringRef RegionType
;
980 SMLoc Loc
= getParser().getTok().getLoc();
981 if (getParser().parseIdentifier(RegionType
))
982 return TokError("expected region type after '.data_region' directive");
983 int Kind
= StringSwitch
<int>(RegionType
)
984 .Case("jt8", MCDR_DataRegionJT8
)
985 .Case("jt16", MCDR_DataRegionJT16
)
986 .Case("jt32", MCDR_DataRegionJT32
)
989 return Error(Loc
, "unknown region type in '.data_region' directive");
992 getStreamer().EmitDataRegion((MCDataRegionType
)Kind
);
996 /// ParseDirectiveDataRegionEnd
997 /// ::= .end_data_region
998 bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef
, SMLoc
) {
999 if (getLexer().isNot(AsmToken::EndOfStatement
))
1000 return TokError("unexpected token in '.end_data_region' directive");
1003 getStreamer().EmitDataRegion(MCDR_DataRegionEnd
);
1007 static bool isSDKVersionToken(const AsmToken
&Tok
) {
1008 return Tok
.is(AsmToken::Identifier
) && Tok
.getIdentifier() == "sdk_version";
1011 /// parseMajorMinorVersionComponent ::= major, minor
1012 bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major
,
1014 const char *VersionName
) {
1015 // Get the major version number.
1016 if (getLexer().isNot(AsmToken::Integer
))
1017 return TokError(Twine("invalid ") + VersionName
+
1018 " major version number, integer expected");
1019 int64_t MajorVal
= getLexer().getTok().getIntVal();
1020 if (MajorVal
> 65535 || MajorVal
<= 0)
1021 return TokError(Twine("invalid ") + VersionName
+ " major version number");
1022 *Major
= (unsigned)MajorVal
;
1024 if (getLexer().isNot(AsmToken::Comma
))
1025 return TokError(Twine(VersionName
) +
1026 " minor version number required, comma expected");
1028 // Get the minor version number.
1029 if (getLexer().isNot(AsmToken::Integer
))
1030 return TokError(Twine("invalid ") + VersionName
+
1031 " minor version number, integer expected");
1032 int64_t MinorVal
= getLexer().getTok().getIntVal();
1033 if (MinorVal
> 255 || MinorVal
< 0)
1034 return TokError(Twine("invalid ") + VersionName
+ " minor version number");
1040 /// parseOptionalTrailingVersionComponent ::= , version_number
1041 bool DarwinAsmParser::parseOptionalTrailingVersionComponent(
1042 unsigned *Component
, const char *ComponentName
) {
1043 assert(getLexer().is(AsmToken::Comma
) && "comma expected");
1045 if (getLexer().isNot(AsmToken::Integer
))
1046 return TokError(Twine("invalid ") + ComponentName
+
1047 " version number, integer expected");
1048 int64_t Val
= getLexer().getTok().getIntVal();
1049 if (Val
> 255 || Val
< 0)
1050 return TokError(Twine("invalid ") + ComponentName
+ " version number");
1056 /// parseVersion ::= parseMajorMinorVersionComponent
1057 /// parseOptionalTrailingVersionComponent
1058 bool DarwinAsmParser::parseVersion(unsigned *Major
, unsigned *Minor
,
1060 if (parseMajorMinorVersionComponent(Major
, Minor
, "OS"))
1063 // Get the update level, if specified
1065 if (getLexer().is(AsmToken::EndOfStatement
) ||
1066 isSDKVersionToken(getLexer().getTok()))
1068 if (getLexer().isNot(AsmToken::Comma
))
1069 return TokError("invalid OS update specifier, comma expected");
1070 if (parseOptionalTrailingVersionComponent(Update
, "OS update"))
1075 bool DarwinAsmParser::parseSDKVersion(VersionTuple
&SDKVersion
) {
1076 assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version");
1078 unsigned Major
, Minor
;
1079 if (parseMajorMinorVersionComponent(&Major
, &Minor
, "SDK"))
1081 SDKVersion
= VersionTuple(Major
, Minor
);
1083 // Get the subminor version, if specified.
1084 if (getLexer().is(AsmToken::Comma
)) {
1086 if (parseOptionalTrailingVersionComponent(&Subminor
, "SDK subminor"))
1088 SDKVersion
= VersionTuple(Major
, Minor
, Subminor
);
1093 void DarwinAsmParser::checkVersion(StringRef Directive
, StringRef Arg
,
1094 SMLoc Loc
, Triple::OSType ExpectedOS
) {
1095 const Triple
&Target
= getContext().getObjectFileInfo()->getTargetTriple();
1096 if (Target
.getOS() != ExpectedOS
)
1097 Warning(Loc
, Twine(Directive
) +
1098 (Arg
.empty() ? Twine() : Twine(' ') + Arg
) +
1099 " used while targeting " + Target
.getOSName());
1101 if (LastVersionDirective
.isValid()) {
1102 Warning(Loc
, "overriding previous version directive");
1103 Note(LastVersionDirective
, "previous definition is here");
1105 LastVersionDirective
= Loc
;
1108 static Triple::OSType
getOSTypeFromMCVM(MCVersionMinType Type
) {
1110 case MCVM_WatchOSVersionMin
: return Triple::WatchOS
;
1111 case MCVM_TvOSVersionMin
: return Triple::TvOS
;
1112 case MCVM_IOSVersionMin
: return Triple::IOS
;
1113 case MCVM_OSXVersionMin
: return Triple::MacOSX
;
1115 llvm_unreachable("Invalid mc version min type");
1119 /// ::= .ios_version_min parseVersion parseSDKVersion
1120 /// | .macosx_version_min parseVersion parseSDKVersion
1121 /// | .tvos_version_min parseVersion parseSDKVersion
1122 /// | .watchos_version_min parseVersion parseSDKVersion
1123 bool DarwinAsmParser::parseVersionMin(StringRef Directive
, SMLoc Loc
,
1124 MCVersionMinType Type
) {
1128 if (parseVersion(&Major
, &Minor
, &Update
))
1131 VersionTuple SDKVersion
;
1132 if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion
))
1135 if (parseToken(AsmToken::EndOfStatement
))
1136 return addErrorSuffix(Twine(" in '") + Directive
+ "' directive");
1138 Triple::OSType ExpectedOS
= getOSTypeFromMCVM(Type
);
1139 checkVersion(Directive
, StringRef(), Loc
, ExpectedOS
);
1140 getStreamer().EmitVersionMin(Type
, Major
, Minor
, Update
, SDKVersion
);
1144 static Triple::OSType
getOSTypeFromPlatform(MachO::PlatformType Type
) {
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_BRIDGEOS
: /* silence warning */ break;
1151 case MachO::PLATFORM_MACCATALYST
: return Triple::IOS
;
1152 case MachO::PLATFORM_IOSSIMULATOR
: /* silence warning */ break;
1153 case MachO::PLATFORM_TVOSSIMULATOR
: /* silence warning */ break;
1154 case MachO::PLATFORM_WATCHOSSIMULATOR
: /* silence warning */ break;
1156 llvm_unreachable("Invalid mach-o platform type");
1159 /// parseBuildVersion
1160 /// ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion
1161 bool DarwinAsmParser::parseBuildVersion(StringRef Directive
, SMLoc Loc
) {
1162 StringRef PlatformName
;
1163 SMLoc PlatformLoc
= getTok().getLoc();
1164 if (getParser().parseIdentifier(PlatformName
))
1165 return TokError("platform name expected");
1167 unsigned Platform
= StringSwitch
<unsigned>(PlatformName
)
1168 .Case("macos", MachO::PLATFORM_MACOS
)
1169 .Case("ios", MachO::PLATFORM_IOS
)
1170 .Case("tvos", MachO::PLATFORM_TVOS
)
1171 .Case("watchos", MachO::PLATFORM_WATCHOS
)
1172 .Case("macCatalyst", MachO::PLATFORM_MACCATALYST
)
1175 return Error(PlatformLoc
, "unknown platform name");
1177 if (getLexer().isNot(AsmToken::Comma
))
1178 return TokError("version number required, comma expected");
1184 if (parseVersion(&Major
, &Minor
, &Update
))
1187 VersionTuple SDKVersion
;
1188 if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion
))
1191 if (parseToken(AsmToken::EndOfStatement
))
1192 return addErrorSuffix(" in '.build_version' directive");
1194 Triple::OSType ExpectedOS
1195 = getOSTypeFromPlatform((MachO::PlatformType
)Platform
);
1196 checkVersion(Directive
, PlatformName
, Loc
, ExpectedOS
);
1197 getStreamer().EmitBuildVersion(Platform
, Major
, Minor
, Update
, SDKVersion
);
1204 MCAsmParserExtension
*createDarwinAsmParser() {
1205 return new DarwinAsmParser
;
1208 } // end llvm namespace