xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCParser/DarwinAsmParser.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
10*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
11*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
12*0b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
13*0b57cec5SDimitry Andric #include "llvm/ADT/Triple.h"
14*0b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
15*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/MachO.h"
16*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
17*0b57cec5SDimitry Andric #include "llvm/MC/MCDirectives.h"
18*0b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h"
19*0b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h"
20*0b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmParser.h"
21*0b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmParserExtension.h"
22*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h"
23*0b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
24*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
25*0b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h"
26*0b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
27*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
28*0b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h"
29*0b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h"
30*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
31*0b57cec5SDimitry Andric #include <algorithm>
32*0b57cec5SDimitry Andric #include <cstddef>
33*0b57cec5SDimitry Andric #include <cstdint>
34*0b57cec5SDimitry Andric #include <string>
35*0b57cec5SDimitry Andric #include <system_error>
36*0b57cec5SDimitry Andric #include <utility>
37*0b57cec5SDimitry Andric 
38*0b57cec5SDimitry Andric using namespace llvm;
39*0b57cec5SDimitry Andric 
40*0b57cec5SDimitry Andric namespace {
41*0b57cec5SDimitry Andric 
42*0b57cec5SDimitry Andric /// Implementation of directive handling which is shared across all
43*0b57cec5SDimitry Andric /// Darwin targets.
44*0b57cec5SDimitry Andric class DarwinAsmParser : public MCAsmParserExtension {
45*0b57cec5SDimitry Andric   template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
46*0b57cec5SDimitry Andric   void addDirectiveHandler(StringRef Directive) {
47*0b57cec5SDimitry Andric     MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
48*0b57cec5SDimitry Andric         this, HandleDirective<DarwinAsmParser, HandlerMethod>);
49*0b57cec5SDimitry Andric     getParser().addDirectiveHandler(Directive, Handler);
50*0b57cec5SDimitry Andric   }
51*0b57cec5SDimitry Andric 
52*0b57cec5SDimitry Andric   bool parseSectionSwitch(StringRef Segment, StringRef Section,
53*0b57cec5SDimitry Andric                           unsigned TAA = 0, unsigned ImplicitAlign = 0,
54*0b57cec5SDimitry Andric                           unsigned StubSize = 0);
55*0b57cec5SDimitry Andric 
56*0b57cec5SDimitry Andric   SMLoc LastVersionDirective;
57*0b57cec5SDimitry Andric 
58*0b57cec5SDimitry Andric public:
59*0b57cec5SDimitry Andric   DarwinAsmParser() = default;
60*0b57cec5SDimitry Andric 
61*0b57cec5SDimitry Andric   void Initialize(MCAsmParser &Parser) override {
62*0b57cec5SDimitry Andric     // Call the base implementation.
63*0b57cec5SDimitry Andric     this->MCAsmParserExtension::Initialize(Parser);
64*0b57cec5SDimitry Andric 
65*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry");
66*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");
67*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(
68*0b57cec5SDimitry Andric       ".indirect_symbol");
69*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym");
70*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>(
71*0b57cec5SDimitry Andric       ".subsections_via_symbols");
72*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump");
73*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load");
74*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section");
75*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>(
76*0b57cec5SDimitry Andric       ".pushsection");
77*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>(
78*0b57cec5SDimitry Andric       ".popsection");
79*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous");
80*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>(
81*0b57cec5SDimitry Andric       ".secure_log_unique");
82*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>(
83*0b57cec5SDimitry Andric       ".secure_log_reset");
84*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss");
85*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill");
86*0b57cec5SDimitry Andric 
87*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>(
88*0b57cec5SDimitry Andric       ".data_region");
89*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>(
90*0b57cec5SDimitry Andric       ".end_data_region");
91*0b57cec5SDimitry Andric 
92*0b57cec5SDimitry Andric     // Special section directives.
93*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss");
94*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const");
95*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>(
96*0b57cec5SDimitry Andric       ".const_data");
97*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>(
98*0b57cec5SDimitry Andric       ".constructor");
99*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>(
100*0b57cec5SDimitry Andric       ".cstring");
101*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data");
102*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>(
103*0b57cec5SDimitry Andric       ".destructor");
104*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld");
105*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>(
106*0b57cec5SDimitry Andric       ".fvmlib_init0");
107*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>(
108*0b57cec5SDimitry Andric       ".fvmlib_init1");
109*0b57cec5SDimitry Andric     addDirectiveHandler<
110*0b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>(
111*0b57cec5SDimitry Andric         ".lazy_symbol_pointer");
112*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>(
113*0b57cec5SDimitry Andric       ".linker_option");
114*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>(
115*0b57cec5SDimitry Andric       ".literal16");
116*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>(
117*0b57cec5SDimitry Andric       ".literal4");
118*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>(
119*0b57cec5SDimitry Andric       ".literal8");
120*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>(
121*0b57cec5SDimitry Andric       ".mod_init_func");
122*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>(
123*0b57cec5SDimitry Andric       ".mod_term_func");
124*0b57cec5SDimitry Andric     addDirectiveHandler<
125*0b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(
126*0b57cec5SDimitry Andric         ".non_lazy_symbol_pointer");
127*0b57cec5SDimitry Andric     addDirectiveHandler<
128*0b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>(
129*0b57cec5SDimitry Andric         ".thread_local_variable_pointer");
130*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(
131*0b57cec5SDimitry Andric       ".objc_cat_cls_meth");
132*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(
133*0b57cec5SDimitry Andric       ".objc_cat_inst_meth");
134*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>(
135*0b57cec5SDimitry Andric       ".objc_category");
136*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>(
137*0b57cec5SDimitry Andric       ".objc_class");
138*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>(
139*0b57cec5SDimitry Andric       ".objc_class_names");
140*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>(
141*0b57cec5SDimitry Andric       ".objc_class_vars");
142*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>(
143*0b57cec5SDimitry Andric       ".objc_cls_meth");
144*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>(
145*0b57cec5SDimitry Andric       ".objc_cls_refs");
146*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>(
147*0b57cec5SDimitry Andric       ".objc_inst_meth");
148*0b57cec5SDimitry Andric     addDirectiveHandler<
149*0b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>(
150*0b57cec5SDimitry Andric         ".objc_instance_vars");
151*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>(
152*0b57cec5SDimitry Andric       ".objc_message_refs");
153*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>(
154*0b57cec5SDimitry Andric       ".objc_meta_class");
155*0b57cec5SDimitry Andric     addDirectiveHandler<
156*0b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>(
157*0b57cec5SDimitry Andric         ".objc_meth_var_names");
158*0b57cec5SDimitry Andric     addDirectiveHandler<
159*0b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>(
160*0b57cec5SDimitry Andric         ".objc_meth_var_types");
161*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>(
162*0b57cec5SDimitry Andric       ".objc_module_info");
163*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>(
164*0b57cec5SDimitry Andric       ".objc_protocol");
165*0b57cec5SDimitry Andric     addDirectiveHandler<
166*0b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>(
167*0b57cec5SDimitry Andric         ".objc_selector_strs");
168*0b57cec5SDimitry Andric     addDirectiveHandler<
169*0b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCStringObject>(
170*0b57cec5SDimitry Andric         ".objc_string_object");
171*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>(
172*0b57cec5SDimitry Andric       ".objc_symbols");
173*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>(
174*0b57cec5SDimitry Andric       ".picsymbol_stub");
175*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>(
176*0b57cec5SDimitry Andric       ".static_const");
177*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>(
178*0b57cec5SDimitry Andric       ".static_data");
179*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>(
180*0b57cec5SDimitry Andric       ".symbol_stub");
181*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata");
182*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text");
183*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>(
184*0b57cec5SDimitry Andric       ".thread_init_func");
185*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
186*0b57cec5SDimitry Andric 
187*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
188*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseWatchOSVersionMin>(
189*0b57cec5SDimitry Andric       ".watchos_version_min");
190*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseTvOSVersionMin>(
191*0b57cec5SDimitry Andric       ".tvos_version_min");
192*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseIOSVersionMin>(
193*0b57cec5SDimitry Andric       ".ios_version_min");
194*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>(
195*0b57cec5SDimitry Andric       ".macosx_version_min");
196*0b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version");
197*0b57cec5SDimitry Andric 
198*0b57cec5SDimitry Andric     LastVersionDirective = SMLoc();
199*0b57cec5SDimitry Andric   }
200*0b57cec5SDimitry Andric 
201*0b57cec5SDimitry Andric   bool parseDirectiveAltEntry(StringRef, SMLoc);
202*0b57cec5SDimitry Andric   bool parseDirectiveDesc(StringRef, SMLoc);
203*0b57cec5SDimitry Andric   bool parseDirectiveIndirectSymbol(StringRef, SMLoc);
204*0b57cec5SDimitry Andric   bool parseDirectiveDumpOrLoad(StringRef, SMLoc);
205*0b57cec5SDimitry Andric   bool parseDirectiveLsym(StringRef, SMLoc);
206*0b57cec5SDimitry Andric   bool parseDirectiveLinkerOption(StringRef, SMLoc);
207*0b57cec5SDimitry Andric   bool parseDirectiveSection(StringRef, SMLoc);
208*0b57cec5SDimitry Andric   bool parseDirectivePushSection(StringRef, SMLoc);
209*0b57cec5SDimitry Andric   bool parseDirectivePopSection(StringRef, SMLoc);
210*0b57cec5SDimitry Andric   bool parseDirectivePrevious(StringRef, SMLoc);
211*0b57cec5SDimitry Andric   bool parseDirectiveSecureLogReset(StringRef, SMLoc);
212*0b57cec5SDimitry Andric   bool parseDirectiveSecureLogUnique(StringRef, SMLoc);
213*0b57cec5SDimitry Andric   bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
214*0b57cec5SDimitry Andric   bool parseDirectiveTBSS(StringRef, SMLoc);
215*0b57cec5SDimitry Andric   bool parseDirectiveZerofill(StringRef, SMLoc);
216*0b57cec5SDimitry Andric   bool parseDirectiveDataRegion(StringRef, SMLoc);
217*0b57cec5SDimitry Andric   bool parseDirectiveDataRegionEnd(StringRef, SMLoc);
218*0b57cec5SDimitry Andric 
219*0b57cec5SDimitry Andric   // Named Section Directive
220*0b57cec5SDimitry Andric   bool parseSectionDirectiveBss(StringRef, SMLoc) {
221*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__bss");
222*0b57cec5SDimitry Andric   }
223*0b57cec5SDimitry Andric 
224*0b57cec5SDimitry Andric   bool parseSectionDirectiveConst(StringRef, SMLoc) {
225*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__const");
226*0b57cec5SDimitry Andric   }
227*0b57cec5SDimitry Andric 
228*0b57cec5SDimitry Andric   bool parseSectionDirectiveStaticConst(StringRef, SMLoc) {
229*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__static_const");
230*0b57cec5SDimitry Andric   }
231*0b57cec5SDimitry Andric 
232*0b57cec5SDimitry Andric   bool parseSectionDirectiveCString(StringRef, SMLoc) {
233*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__cstring",
234*0b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
235*0b57cec5SDimitry Andric   }
236*0b57cec5SDimitry Andric 
237*0b57cec5SDimitry Andric   bool parseSectionDirectiveLiteral4(StringRef, SMLoc) {
238*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__literal4",
239*0b57cec5SDimitry Andric                               MachO::S_4BYTE_LITERALS, 4);
240*0b57cec5SDimitry Andric   }
241*0b57cec5SDimitry Andric 
242*0b57cec5SDimitry Andric   bool parseSectionDirectiveLiteral8(StringRef, SMLoc) {
243*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__literal8",
244*0b57cec5SDimitry Andric                               MachO::S_8BYTE_LITERALS, 8);
245*0b57cec5SDimitry Andric   }
246*0b57cec5SDimitry Andric 
247*0b57cec5SDimitry Andric   bool parseSectionDirectiveLiteral16(StringRef, SMLoc) {
248*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__literal16",
249*0b57cec5SDimitry Andric                               MachO::S_16BYTE_LITERALS, 16);
250*0b57cec5SDimitry Andric   }
251*0b57cec5SDimitry Andric 
252*0b57cec5SDimitry Andric   bool parseSectionDirectiveConstructor(StringRef, SMLoc) {
253*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__constructor");
254*0b57cec5SDimitry Andric   }
255*0b57cec5SDimitry Andric 
256*0b57cec5SDimitry Andric   bool parseSectionDirectiveDestructor(StringRef, SMLoc) {
257*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__destructor");
258*0b57cec5SDimitry Andric   }
259*0b57cec5SDimitry Andric 
260*0b57cec5SDimitry Andric   bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
261*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__fvmlib_init0");
262*0b57cec5SDimitry Andric   }
263*0b57cec5SDimitry Andric 
264*0b57cec5SDimitry Andric   bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
265*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__fvmlib_init1");
266*0b57cec5SDimitry Andric   }
267*0b57cec5SDimitry Andric 
268*0b57cec5SDimitry Andric   bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {
269*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__symbol_stub",
270*0b57cec5SDimitry Andric                               MachO::S_SYMBOL_STUBS |
271*0b57cec5SDimitry Andric                               MachO::S_ATTR_PURE_INSTRUCTIONS,
272*0b57cec5SDimitry Andric                               // FIXME: Different on PPC and ARM.
273*0b57cec5SDimitry Andric                               0, 16);
274*0b57cec5SDimitry Andric   }
275*0b57cec5SDimitry Andric 
276*0b57cec5SDimitry Andric   bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
277*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__picsymbol_stub",
278*0b57cec5SDimitry Andric                               MachO::S_SYMBOL_STUBS |
279*0b57cec5SDimitry Andric                               MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
280*0b57cec5SDimitry Andric   }
281*0b57cec5SDimitry Andric 
282*0b57cec5SDimitry Andric   bool parseSectionDirectiveData(StringRef, SMLoc) {
283*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__data");
284*0b57cec5SDimitry Andric   }
285*0b57cec5SDimitry Andric 
286*0b57cec5SDimitry Andric   bool parseSectionDirectiveStaticData(StringRef, SMLoc) {
287*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__static_data");
288*0b57cec5SDimitry Andric   }
289*0b57cec5SDimitry Andric 
290*0b57cec5SDimitry Andric   bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
291*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__nl_symbol_ptr",
292*0b57cec5SDimitry Andric                               MachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
293*0b57cec5SDimitry Andric   }
294*0b57cec5SDimitry Andric 
295*0b57cec5SDimitry Andric   bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
296*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__la_symbol_ptr",
297*0b57cec5SDimitry Andric                               MachO::S_LAZY_SYMBOL_POINTERS, 4);
298*0b57cec5SDimitry Andric   }
299*0b57cec5SDimitry Andric 
300*0b57cec5SDimitry Andric   bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) {
301*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_ptr",
302*0b57cec5SDimitry Andric                               MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4);
303*0b57cec5SDimitry Andric   }
304*0b57cec5SDimitry Andric 
305*0b57cec5SDimitry Andric   bool parseSectionDirectiveDyld(StringRef, SMLoc) {
306*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__dyld");
307*0b57cec5SDimitry Andric   }
308*0b57cec5SDimitry Andric 
309*0b57cec5SDimitry Andric   bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) {
310*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__mod_init_func",
311*0b57cec5SDimitry Andric                               MachO::S_MOD_INIT_FUNC_POINTERS, 4);
312*0b57cec5SDimitry Andric   }
313*0b57cec5SDimitry Andric 
314*0b57cec5SDimitry Andric   bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) {
315*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__mod_term_func",
316*0b57cec5SDimitry Andric                               MachO::S_MOD_TERM_FUNC_POINTERS, 4);
317*0b57cec5SDimitry Andric   }
318*0b57cec5SDimitry Andric 
319*0b57cec5SDimitry Andric   bool parseSectionDirectiveConstData(StringRef, SMLoc) {
320*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__const");
321*0b57cec5SDimitry Andric   }
322*0b57cec5SDimitry Andric 
323*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClass(StringRef, SMLoc) {
324*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__class",
325*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
326*0b57cec5SDimitry Andric   }
327*0b57cec5SDimitry Andric 
328*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
329*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__meta_class",
330*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
331*0b57cec5SDimitry Andric   }
332*0b57cec5SDimitry Andric 
333*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
334*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cat_cls_meth",
335*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
336*0b57cec5SDimitry Andric   }
337*0b57cec5SDimitry Andric 
338*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
339*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cat_inst_meth",
340*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
341*0b57cec5SDimitry Andric   }
342*0b57cec5SDimitry Andric 
343*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
344*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__protocol",
345*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
346*0b57cec5SDimitry Andric   }
347*0b57cec5SDimitry Andric 
348*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
349*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__string_object",
350*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
351*0b57cec5SDimitry Andric   }
352*0b57cec5SDimitry Andric 
353*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
354*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cls_meth",
355*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
356*0b57cec5SDimitry Andric   }
357*0b57cec5SDimitry Andric 
358*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
359*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__inst_meth",
360*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
361*0b57cec5SDimitry Andric   }
362*0b57cec5SDimitry Andric 
363*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
364*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cls_refs",
365*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP |
366*0b57cec5SDimitry Andric                               MachO::S_LITERAL_POINTERS, 4);
367*0b57cec5SDimitry Andric   }
368*0b57cec5SDimitry Andric 
369*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
370*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__message_refs",
371*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP |
372*0b57cec5SDimitry Andric                               MachO::S_LITERAL_POINTERS, 4);
373*0b57cec5SDimitry Andric   }
374*0b57cec5SDimitry Andric 
375*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
376*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__symbols",
377*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
378*0b57cec5SDimitry Andric   }
379*0b57cec5SDimitry Andric 
380*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) {
381*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__category",
382*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
383*0b57cec5SDimitry Andric   }
384*0b57cec5SDimitry Andric 
385*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
386*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__class_vars",
387*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
388*0b57cec5SDimitry Andric   }
389*0b57cec5SDimitry Andric 
390*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
391*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__instance_vars",
392*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
393*0b57cec5SDimitry Andric   }
394*0b57cec5SDimitry Andric 
395*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
396*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__module_info",
397*0b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
398*0b57cec5SDimitry Andric   }
399*0b57cec5SDimitry Andric 
400*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
401*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__cstring",
402*0b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
403*0b57cec5SDimitry Andric   }
404*0b57cec5SDimitry Andric 
405*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
406*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__cstring",
407*0b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
408*0b57cec5SDimitry Andric   }
409*0b57cec5SDimitry Andric 
410*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
411*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__cstring",
412*0b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
413*0b57cec5SDimitry Andric   }
414*0b57cec5SDimitry Andric 
415*0b57cec5SDimitry Andric   bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
416*0b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__selector_strs",
417*0b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
418*0b57cec5SDimitry Andric   }
419*0b57cec5SDimitry Andric 
420*0b57cec5SDimitry Andric   bool parseSectionDirectiveTData(StringRef, SMLoc) {
421*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_data",
422*0b57cec5SDimitry Andric                               MachO::S_THREAD_LOCAL_REGULAR);
423*0b57cec5SDimitry Andric   }
424*0b57cec5SDimitry Andric 
425*0b57cec5SDimitry Andric   bool parseSectionDirectiveText(StringRef, SMLoc) {
426*0b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__text",
427*0b57cec5SDimitry Andric                               MachO::S_ATTR_PURE_INSTRUCTIONS);
428*0b57cec5SDimitry Andric   }
429*0b57cec5SDimitry Andric 
430*0b57cec5SDimitry Andric   bool parseSectionDirectiveTLV(StringRef, SMLoc) {
431*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_vars",
432*0b57cec5SDimitry Andric                               MachO::S_THREAD_LOCAL_VARIABLES);
433*0b57cec5SDimitry Andric   }
434*0b57cec5SDimitry Andric 
435*0b57cec5SDimitry Andric   bool parseSectionDirectiveIdent(StringRef, SMLoc) {
436*0b57cec5SDimitry Andric     // Darwin silently ignores the .ident directive.
437*0b57cec5SDimitry Andric     getParser().eatToEndOfStatement();
438*0b57cec5SDimitry Andric     return false;
439*0b57cec5SDimitry Andric   }
440*0b57cec5SDimitry Andric 
441*0b57cec5SDimitry Andric   bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
442*0b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_init",
443*0b57cec5SDimitry Andric                          MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
444*0b57cec5SDimitry Andric   }
445*0b57cec5SDimitry Andric 
446*0b57cec5SDimitry Andric   bool parseWatchOSVersionMin(StringRef Directive, SMLoc Loc) {
447*0b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_WatchOSVersionMin);
448*0b57cec5SDimitry Andric   }
449*0b57cec5SDimitry Andric   bool parseTvOSVersionMin(StringRef Directive, SMLoc Loc) {
450*0b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_TvOSVersionMin);
451*0b57cec5SDimitry Andric   }
452*0b57cec5SDimitry Andric   bool parseIOSVersionMin(StringRef Directive, SMLoc Loc) {
453*0b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_IOSVersionMin);
454*0b57cec5SDimitry Andric   }
455*0b57cec5SDimitry Andric   bool parseMacOSXVersionMin(StringRef Directive, SMLoc Loc) {
456*0b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_OSXVersionMin);
457*0b57cec5SDimitry Andric   }
458*0b57cec5SDimitry Andric 
459*0b57cec5SDimitry Andric   bool parseBuildVersion(StringRef Directive, SMLoc Loc);
460*0b57cec5SDimitry Andric   bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type);
461*0b57cec5SDimitry Andric   bool parseMajorMinorVersionComponent(unsigned *Major, unsigned *Minor,
462*0b57cec5SDimitry Andric                                        const char *VersionName);
463*0b57cec5SDimitry Andric   bool parseOptionalTrailingVersionComponent(unsigned *Component,
464*0b57cec5SDimitry Andric                                              const char *ComponentName);
465*0b57cec5SDimitry Andric   bool parseVersion(unsigned *Major, unsigned *Minor, unsigned *Update);
466*0b57cec5SDimitry Andric   bool parseSDKVersion(VersionTuple &SDKVersion);
467*0b57cec5SDimitry Andric   void checkVersion(StringRef Directive, StringRef Arg, SMLoc Loc,
468*0b57cec5SDimitry Andric                     Triple::OSType ExpectedOS);
469*0b57cec5SDimitry Andric };
470*0b57cec5SDimitry Andric 
471*0b57cec5SDimitry Andric } // end anonymous namespace
472*0b57cec5SDimitry Andric 
473*0b57cec5SDimitry Andric bool DarwinAsmParser::parseSectionSwitch(StringRef Segment, StringRef Section,
474*0b57cec5SDimitry Andric                                          unsigned TAA, unsigned Align,
475*0b57cec5SDimitry Andric                                          unsigned StubSize) {
476*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
477*0b57cec5SDimitry Andric     return TokError("unexpected token in section switching directive");
478*0b57cec5SDimitry Andric   Lex();
479*0b57cec5SDimitry Andric 
480*0b57cec5SDimitry Andric   // FIXME: Arch specific.
481*0b57cec5SDimitry Andric   bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS;
482*0b57cec5SDimitry Andric   getStreamer().SwitchSection(getContext().getMachOSection(
483*0b57cec5SDimitry Andric       Segment, Section, TAA, StubSize,
484*0b57cec5SDimitry Andric       isText ? SectionKind::getText() : SectionKind::getData()));
485*0b57cec5SDimitry Andric 
486*0b57cec5SDimitry Andric   // Set the implicit alignment, if any.
487*0b57cec5SDimitry Andric   //
488*0b57cec5SDimitry Andric   // FIXME: This isn't really what 'as' does; I think it just uses the implicit
489*0b57cec5SDimitry Andric   // alignment on the section (e.g., if one manually inserts bytes into the
490*0b57cec5SDimitry Andric   // section, then just issuing the section switch directive will not realign
491*0b57cec5SDimitry Andric   // the section. However, this is arguably more reasonable behavior, and there
492*0b57cec5SDimitry Andric   // is no good reason for someone to intentionally emit incorrectly sized
493*0b57cec5SDimitry Andric   // values into the implicitly aligned sections.
494*0b57cec5SDimitry Andric   if (Align)
495*0b57cec5SDimitry Andric     getStreamer().EmitValueToAlignment(Align);
496*0b57cec5SDimitry Andric 
497*0b57cec5SDimitry Andric   return false;
498*0b57cec5SDimitry Andric }
499*0b57cec5SDimitry Andric 
500*0b57cec5SDimitry Andric /// parseDirectiveAltEntry
501*0b57cec5SDimitry Andric ///  ::= .alt_entry identifier
502*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) {
503*0b57cec5SDimitry Andric   StringRef Name;
504*0b57cec5SDimitry Andric   if (getParser().parseIdentifier(Name))
505*0b57cec5SDimitry Andric     return TokError("expected identifier in directive");
506*0b57cec5SDimitry Andric 
507*0b57cec5SDimitry Andric   // Look up symbol.
508*0b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
509*0b57cec5SDimitry Andric 
510*0b57cec5SDimitry Andric   if (Sym->isDefined())
511*0b57cec5SDimitry Andric     return TokError(".alt_entry must preceed symbol definition");
512*0b57cec5SDimitry Andric 
513*0b57cec5SDimitry Andric   if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_AltEntry))
514*0b57cec5SDimitry Andric     return TokError("unable to emit symbol attribute");
515*0b57cec5SDimitry Andric 
516*0b57cec5SDimitry Andric   Lex();
517*0b57cec5SDimitry Andric   return false;
518*0b57cec5SDimitry Andric }
519*0b57cec5SDimitry Andric 
520*0b57cec5SDimitry Andric /// parseDirectiveDesc
521*0b57cec5SDimitry Andric ///  ::= .desc identifier , expression
522*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {
523*0b57cec5SDimitry Andric   StringRef Name;
524*0b57cec5SDimitry Andric   if (getParser().parseIdentifier(Name))
525*0b57cec5SDimitry Andric     return TokError("expected identifier in directive");
526*0b57cec5SDimitry Andric 
527*0b57cec5SDimitry Andric   // Handle the identifier as the key symbol.
528*0b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
529*0b57cec5SDimitry Andric 
530*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
531*0b57cec5SDimitry Andric     return TokError("unexpected token in '.desc' directive");
532*0b57cec5SDimitry Andric   Lex();
533*0b57cec5SDimitry Andric 
534*0b57cec5SDimitry Andric   int64_t DescValue;
535*0b57cec5SDimitry Andric   if (getParser().parseAbsoluteExpression(DescValue))
536*0b57cec5SDimitry Andric     return true;
537*0b57cec5SDimitry Andric 
538*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
539*0b57cec5SDimitry Andric     return TokError("unexpected token in '.desc' directive");
540*0b57cec5SDimitry Andric 
541*0b57cec5SDimitry Andric   Lex();
542*0b57cec5SDimitry Andric 
543*0b57cec5SDimitry Andric   // Set the n_desc field of this Symbol to this DescValue
544*0b57cec5SDimitry Andric   getStreamer().EmitSymbolDesc(Sym, DescValue);
545*0b57cec5SDimitry Andric 
546*0b57cec5SDimitry Andric   return false;
547*0b57cec5SDimitry Andric }
548*0b57cec5SDimitry Andric 
549*0b57cec5SDimitry Andric /// parseDirectiveIndirectSymbol
550*0b57cec5SDimitry Andric ///  ::= .indirect_symbol identifier
551*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
552*0b57cec5SDimitry Andric   const MCSectionMachO *Current = static_cast<const MCSectionMachO *>(
553*0b57cec5SDimitry Andric       getStreamer().getCurrentSectionOnly());
554*0b57cec5SDimitry Andric   MachO::SectionType SectionType = Current->getType();
555*0b57cec5SDimitry Andric   if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
556*0b57cec5SDimitry Andric       SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&
557*0b57cec5SDimitry Andric       SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS &&
558*0b57cec5SDimitry Andric       SectionType != MachO::S_SYMBOL_STUBS)
559*0b57cec5SDimitry Andric     return Error(Loc, "indirect symbol not in a symbol pointer or stub "
560*0b57cec5SDimitry Andric                       "section");
561*0b57cec5SDimitry Andric 
562*0b57cec5SDimitry Andric   StringRef Name;
563*0b57cec5SDimitry Andric   if (getParser().parseIdentifier(Name))
564*0b57cec5SDimitry Andric     return TokError("expected identifier in .indirect_symbol directive");
565*0b57cec5SDimitry Andric 
566*0b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
567*0b57cec5SDimitry Andric 
568*0b57cec5SDimitry Andric   // Assembler local symbols don't make any sense here. Complain loudly.
569*0b57cec5SDimitry Andric   if (Sym->isTemporary())
570*0b57cec5SDimitry Andric     return TokError("non-local symbol required in directive");
571*0b57cec5SDimitry Andric 
572*0b57cec5SDimitry Andric   if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol))
573*0b57cec5SDimitry Andric     return TokError("unable to emit indirect symbol attribute for: " + Name);
574*0b57cec5SDimitry Andric 
575*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
576*0b57cec5SDimitry Andric     return TokError("unexpected token in '.indirect_symbol' directive");
577*0b57cec5SDimitry Andric 
578*0b57cec5SDimitry Andric   Lex();
579*0b57cec5SDimitry Andric 
580*0b57cec5SDimitry Andric   return false;
581*0b57cec5SDimitry Andric }
582*0b57cec5SDimitry Andric 
583*0b57cec5SDimitry Andric /// parseDirectiveDumpOrLoad
584*0b57cec5SDimitry Andric ///  ::= ( .dump | .load ) "filename"
585*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive,
586*0b57cec5SDimitry Andric                                                SMLoc IDLoc) {
587*0b57cec5SDimitry Andric   bool IsDump = Directive == ".dump";
588*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::String))
589*0b57cec5SDimitry Andric     return TokError("expected string in '.dump' or '.load' directive");
590*0b57cec5SDimitry Andric 
591*0b57cec5SDimitry Andric   Lex();
592*0b57cec5SDimitry Andric 
593*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
594*0b57cec5SDimitry Andric     return TokError("unexpected token in '.dump' or '.load' directive");
595*0b57cec5SDimitry Andric 
596*0b57cec5SDimitry Andric   Lex();
597*0b57cec5SDimitry Andric 
598*0b57cec5SDimitry Andric   // FIXME: If/when .dump and .load are implemented they will be done in the
599*0b57cec5SDimitry Andric   // the assembly parser and not have any need for an MCStreamer API.
600*0b57cec5SDimitry Andric   if (IsDump)
601*0b57cec5SDimitry Andric     return Warning(IDLoc, "ignoring directive .dump for now");
602*0b57cec5SDimitry Andric   else
603*0b57cec5SDimitry Andric     return Warning(IDLoc, "ignoring directive .load for now");
604*0b57cec5SDimitry Andric }
605*0b57cec5SDimitry Andric 
606*0b57cec5SDimitry Andric /// ParseDirectiveLinkerOption
607*0b57cec5SDimitry Andric ///  ::= .linker_option "string" ( , "string" )*
608*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
609*0b57cec5SDimitry Andric   SmallVector<std::string, 4> Args;
610*0b57cec5SDimitry Andric   while (true) {
611*0b57cec5SDimitry Andric     if (getLexer().isNot(AsmToken::String))
612*0b57cec5SDimitry Andric       return TokError("expected string in '" + Twine(IDVal) + "' directive");
613*0b57cec5SDimitry Andric 
614*0b57cec5SDimitry Andric     std::string Data;
615*0b57cec5SDimitry Andric     if (getParser().parseEscapedString(Data))
616*0b57cec5SDimitry Andric       return true;
617*0b57cec5SDimitry Andric 
618*0b57cec5SDimitry Andric     Args.push_back(Data);
619*0b57cec5SDimitry Andric 
620*0b57cec5SDimitry Andric     if (getLexer().is(AsmToken::EndOfStatement))
621*0b57cec5SDimitry Andric       break;
622*0b57cec5SDimitry Andric 
623*0b57cec5SDimitry Andric     if (getLexer().isNot(AsmToken::Comma))
624*0b57cec5SDimitry Andric       return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
625*0b57cec5SDimitry Andric     Lex();
626*0b57cec5SDimitry Andric   }
627*0b57cec5SDimitry Andric 
628*0b57cec5SDimitry Andric   getStreamer().EmitLinkerOptions(Args);
629*0b57cec5SDimitry Andric   return false;
630*0b57cec5SDimitry Andric }
631*0b57cec5SDimitry Andric 
632*0b57cec5SDimitry Andric /// parseDirectiveLsym
633*0b57cec5SDimitry Andric ///  ::= .lsym identifier , expression
634*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) {
635*0b57cec5SDimitry Andric   StringRef Name;
636*0b57cec5SDimitry Andric   if (getParser().parseIdentifier(Name))
637*0b57cec5SDimitry Andric     return TokError("expected identifier in directive");
638*0b57cec5SDimitry Andric 
639*0b57cec5SDimitry Andric   // Handle the identifier as the key symbol.
640*0b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
641*0b57cec5SDimitry Andric 
642*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
643*0b57cec5SDimitry Andric     return TokError("unexpected token in '.lsym' directive");
644*0b57cec5SDimitry Andric   Lex();
645*0b57cec5SDimitry Andric 
646*0b57cec5SDimitry Andric   const MCExpr *Value;
647*0b57cec5SDimitry Andric   if (getParser().parseExpression(Value))
648*0b57cec5SDimitry Andric     return true;
649*0b57cec5SDimitry Andric 
650*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
651*0b57cec5SDimitry Andric     return TokError("unexpected token in '.lsym' directive");
652*0b57cec5SDimitry Andric 
653*0b57cec5SDimitry Andric   Lex();
654*0b57cec5SDimitry Andric 
655*0b57cec5SDimitry Andric   // We don't currently support this directive.
656*0b57cec5SDimitry Andric   //
657*0b57cec5SDimitry Andric   // FIXME: Diagnostic location!
658*0b57cec5SDimitry Andric   (void) Sym;
659*0b57cec5SDimitry Andric   return TokError("directive '.lsym' is unsupported");
660*0b57cec5SDimitry Andric }
661*0b57cec5SDimitry Andric 
662*0b57cec5SDimitry Andric /// parseDirectiveSection:
663*0b57cec5SDimitry Andric ///   ::= .section identifier (',' identifier)*
664*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {
665*0b57cec5SDimitry Andric   SMLoc Loc = getLexer().getLoc();
666*0b57cec5SDimitry Andric 
667*0b57cec5SDimitry Andric   StringRef SectionName;
668*0b57cec5SDimitry Andric   if (getParser().parseIdentifier(SectionName))
669*0b57cec5SDimitry Andric     return Error(Loc, "expected identifier after '.section' directive");
670*0b57cec5SDimitry Andric 
671*0b57cec5SDimitry Andric   // Verify there is a following comma.
672*0b57cec5SDimitry Andric   if (!getLexer().is(AsmToken::Comma))
673*0b57cec5SDimitry Andric     return TokError("unexpected token in '.section' directive");
674*0b57cec5SDimitry Andric 
675*0b57cec5SDimitry Andric   std::string SectionSpec = SectionName;
676*0b57cec5SDimitry Andric   SectionSpec += ",";
677*0b57cec5SDimitry Andric 
678*0b57cec5SDimitry Andric   // Add all the tokens until the end of the line, ParseSectionSpecifier will
679*0b57cec5SDimitry Andric   // handle this.
680*0b57cec5SDimitry Andric   StringRef EOL = getLexer().LexUntilEndOfStatement();
681*0b57cec5SDimitry Andric   SectionSpec.append(EOL.begin(), EOL.end());
682*0b57cec5SDimitry Andric 
683*0b57cec5SDimitry Andric   Lex();
684*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
685*0b57cec5SDimitry Andric     return TokError("unexpected token in '.section' directive");
686*0b57cec5SDimitry Andric   Lex();
687*0b57cec5SDimitry Andric 
688*0b57cec5SDimitry Andric   StringRef Segment, Section;
689*0b57cec5SDimitry Andric   unsigned StubSize;
690*0b57cec5SDimitry Andric   unsigned TAA;
691*0b57cec5SDimitry Andric   bool TAAParsed;
692*0b57cec5SDimitry Andric   std::string ErrorStr =
693*0b57cec5SDimitry Andric     MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
694*0b57cec5SDimitry Andric                                           TAA, TAAParsed, StubSize);
695*0b57cec5SDimitry Andric 
696*0b57cec5SDimitry Andric   if (!ErrorStr.empty())
697*0b57cec5SDimitry Andric     return Error(Loc, ErrorStr);
698*0b57cec5SDimitry Andric 
699*0b57cec5SDimitry Andric   // Issue a warning if the target is not powerpc and Section is a *coal* section.
700*0b57cec5SDimitry Andric   Triple TT = getParser().getContext().getObjectFileInfo()->getTargetTriple();
701*0b57cec5SDimitry Andric   Triple::ArchType ArchTy = TT.getArch();
702*0b57cec5SDimitry Andric 
703*0b57cec5SDimitry Andric   if (ArchTy != Triple::ppc && ArchTy != Triple::ppc64) {
704*0b57cec5SDimitry Andric     StringRef NonCoalSection = StringSwitch<StringRef>(Section)
705*0b57cec5SDimitry Andric                                    .Case("__textcoal_nt", "__text")
706*0b57cec5SDimitry Andric                                    .Case("__const_coal", "__const")
707*0b57cec5SDimitry Andric                                    .Case("__datacoal_nt", "__data")
708*0b57cec5SDimitry Andric                                    .Default(Section);
709*0b57cec5SDimitry Andric 
710*0b57cec5SDimitry Andric     if (!Section.equals(NonCoalSection)) {
711*0b57cec5SDimitry Andric       StringRef SectionVal(Loc.getPointer());
712*0b57cec5SDimitry Andric       size_t B = SectionVal.find(',') + 1, E = SectionVal.find(',', B);
713*0b57cec5SDimitry Andric       SMLoc BLoc = SMLoc::getFromPointer(SectionVal.data() + B);
714*0b57cec5SDimitry Andric       SMLoc ELoc = SMLoc::getFromPointer(SectionVal.data() + E);
715*0b57cec5SDimitry Andric       getParser().Warning(Loc, "section \"" + Section + "\" is deprecated",
716*0b57cec5SDimitry Andric                           SMRange(BLoc, ELoc));
717*0b57cec5SDimitry Andric       getParser().Note(Loc, "change section name to \"" + NonCoalSection +
718*0b57cec5SDimitry Andric                        "\"", SMRange(BLoc, ELoc));
719*0b57cec5SDimitry Andric     }
720*0b57cec5SDimitry Andric   }
721*0b57cec5SDimitry Andric 
722*0b57cec5SDimitry Andric   // FIXME: Arch specific.
723*0b57cec5SDimitry Andric   bool isText = Segment == "__TEXT";  // FIXME: Hack.
724*0b57cec5SDimitry Andric   getStreamer().SwitchSection(getContext().getMachOSection(
725*0b57cec5SDimitry Andric       Segment, Section, TAA, StubSize,
726*0b57cec5SDimitry Andric       isText ? SectionKind::getText() : SectionKind::getData()));
727*0b57cec5SDimitry Andric   return false;
728*0b57cec5SDimitry Andric }
729*0b57cec5SDimitry Andric 
730*0b57cec5SDimitry Andric /// ParseDirectivePushSection:
731*0b57cec5SDimitry Andric ///   ::= .pushsection identifier (',' identifier)*
732*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) {
733*0b57cec5SDimitry Andric   getStreamer().PushSection();
734*0b57cec5SDimitry Andric 
735*0b57cec5SDimitry Andric   if (parseDirectiveSection(S, Loc)) {
736*0b57cec5SDimitry Andric     getStreamer().PopSection();
737*0b57cec5SDimitry Andric     return true;
738*0b57cec5SDimitry Andric   }
739*0b57cec5SDimitry Andric 
740*0b57cec5SDimitry Andric   return false;
741*0b57cec5SDimitry Andric }
742*0b57cec5SDimitry Andric 
743*0b57cec5SDimitry Andric /// ParseDirectivePopSection:
744*0b57cec5SDimitry Andric ///   ::= .popsection
745*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
746*0b57cec5SDimitry Andric   if (!getStreamer().PopSection())
747*0b57cec5SDimitry Andric     return TokError(".popsection without corresponding .pushsection");
748*0b57cec5SDimitry Andric   return false;
749*0b57cec5SDimitry Andric }
750*0b57cec5SDimitry Andric 
751*0b57cec5SDimitry Andric /// ParseDirectivePrevious:
752*0b57cec5SDimitry Andric ///   ::= .previous
753*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {
754*0b57cec5SDimitry Andric   MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
755*0b57cec5SDimitry Andric   if (!PreviousSection.first)
756*0b57cec5SDimitry Andric     return TokError(".previous without corresponding .section");
757*0b57cec5SDimitry Andric   getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
758*0b57cec5SDimitry Andric   return false;
759*0b57cec5SDimitry Andric }
760*0b57cec5SDimitry Andric 
761*0b57cec5SDimitry Andric /// ParseDirectiveSecureLogUnique
762*0b57cec5SDimitry Andric ///  ::= .secure_log_unique ... message ...
763*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
764*0b57cec5SDimitry Andric   StringRef LogMessage = getParser().parseStringToEndOfStatement();
765*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
766*0b57cec5SDimitry Andric     return TokError("unexpected token in '.secure_log_unique' directive");
767*0b57cec5SDimitry Andric 
768*0b57cec5SDimitry Andric   if (getContext().getSecureLogUsed())
769*0b57cec5SDimitry Andric     return Error(IDLoc, ".secure_log_unique specified multiple times");
770*0b57cec5SDimitry Andric 
771*0b57cec5SDimitry Andric   // Get the secure log path.
772*0b57cec5SDimitry Andric   const char *SecureLogFile = getContext().getSecureLogFile();
773*0b57cec5SDimitry Andric   if (!SecureLogFile)
774*0b57cec5SDimitry Andric     return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
775*0b57cec5SDimitry Andric                  "environment variable unset.");
776*0b57cec5SDimitry Andric 
777*0b57cec5SDimitry Andric   // Open the secure log file if we haven't already.
778*0b57cec5SDimitry Andric   raw_fd_ostream *OS = getContext().getSecureLog();
779*0b57cec5SDimitry Andric   if (!OS) {
780*0b57cec5SDimitry Andric     std::error_code EC;
781*0b57cec5SDimitry Andric     auto NewOS = llvm::make_unique<raw_fd_ostream>(
782*0b57cec5SDimitry Andric         StringRef(SecureLogFile), EC, sys::fs::F_Append | sys::fs::F_Text);
783*0b57cec5SDimitry Andric     if (EC)
784*0b57cec5SDimitry Andric        return Error(IDLoc, Twine("can't open secure log file: ") +
785*0b57cec5SDimitry Andric                                SecureLogFile + " (" + EC.message() + ")");
786*0b57cec5SDimitry Andric     OS = NewOS.get();
787*0b57cec5SDimitry Andric     getContext().setSecureLog(std::move(NewOS));
788*0b57cec5SDimitry Andric   }
789*0b57cec5SDimitry Andric 
790*0b57cec5SDimitry Andric   // Write the message.
791*0b57cec5SDimitry Andric   unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
792*0b57cec5SDimitry Andric   *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
793*0b57cec5SDimitry Andric       << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
794*0b57cec5SDimitry Andric       << LogMessage + "\n";
795*0b57cec5SDimitry Andric 
796*0b57cec5SDimitry Andric   getContext().setSecureLogUsed(true);
797*0b57cec5SDimitry Andric 
798*0b57cec5SDimitry Andric   return false;
799*0b57cec5SDimitry Andric }
800*0b57cec5SDimitry Andric 
801*0b57cec5SDimitry Andric /// ParseDirectiveSecureLogReset
802*0b57cec5SDimitry Andric ///  ::= .secure_log_reset
803*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
804*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
805*0b57cec5SDimitry Andric     return TokError("unexpected token in '.secure_log_reset' directive");
806*0b57cec5SDimitry Andric 
807*0b57cec5SDimitry Andric   Lex();
808*0b57cec5SDimitry Andric 
809*0b57cec5SDimitry Andric   getContext().setSecureLogUsed(false);
810*0b57cec5SDimitry Andric 
811*0b57cec5SDimitry Andric   return false;
812*0b57cec5SDimitry Andric }
813*0b57cec5SDimitry Andric 
814*0b57cec5SDimitry Andric /// parseDirectiveSubsectionsViaSymbols
815*0b57cec5SDimitry Andric ///  ::= .subsections_via_symbols
816*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
817*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
818*0b57cec5SDimitry Andric     return TokError("unexpected token in '.subsections_via_symbols' directive");
819*0b57cec5SDimitry Andric 
820*0b57cec5SDimitry Andric   Lex();
821*0b57cec5SDimitry Andric 
822*0b57cec5SDimitry Andric   getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
823*0b57cec5SDimitry Andric 
824*0b57cec5SDimitry Andric   return false;
825*0b57cec5SDimitry Andric }
826*0b57cec5SDimitry Andric 
827*0b57cec5SDimitry Andric /// ParseDirectiveTBSS
828*0b57cec5SDimitry Andric ///  ::= .tbss identifier, size, align
829*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) {
830*0b57cec5SDimitry Andric   SMLoc IDLoc = getLexer().getLoc();
831*0b57cec5SDimitry Andric   StringRef Name;
832*0b57cec5SDimitry Andric   if (getParser().parseIdentifier(Name))
833*0b57cec5SDimitry Andric     return TokError("expected identifier in directive");
834*0b57cec5SDimitry Andric 
835*0b57cec5SDimitry Andric   // Handle the identifier as the key symbol.
836*0b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
837*0b57cec5SDimitry Andric 
838*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
839*0b57cec5SDimitry Andric     return TokError("unexpected token in directive");
840*0b57cec5SDimitry Andric   Lex();
841*0b57cec5SDimitry Andric 
842*0b57cec5SDimitry Andric   int64_t Size;
843*0b57cec5SDimitry Andric   SMLoc SizeLoc = getLexer().getLoc();
844*0b57cec5SDimitry Andric   if (getParser().parseAbsoluteExpression(Size))
845*0b57cec5SDimitry Andric     return true;
846*0b57cec5SDimitry Andric 
847*0b57cec5SDimitry Andric   int64_t Pow2Alignment = 0;
848*0b57cec5SDimitry Andric   SMLoc Pow2AlignmentLoc;
849*0b57cec5SDimitry Andric   if (getLexer().is(AsmToken::Comma)) {
850*0b57cec5SDimitry Andric     Lex();
851*0b57cec5SDimitry Andric     Pow2AlignmentLoc = getLexer().getLoc();
852*0b57cec5SDimitry Andric     if (getParser().parseAbsoluteExpression(Pow2Alignment))
853*0b57cec5SDimitry Andric       return true;
854*0b57cec5SDimitry Andric   }
855*0b57cec5SDimitry Andric 
856*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
857*0b57cec5SDimitry Andric     return TokError("unexpected token in '.tbss' directive");
858*0b57cec5SDimitry Andric 
859*0b57cec5SDimitry Andric   Lex();
860*0b57cec5SDimitry Andric 
861*0b57cec5SDimitry Andric   if (Size < 0)
862*0b57cec5SDimitry Andric     return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
863*0b57cec5SDimitry Andric                  "zero");
864*0b57cec5SDimitry Andric 
865*0b57cec5SDimitry Andric   // FIXME: Diagnose overflow.
866*0b57cec5SDimitry Andric   if (Pow2Alignment < 0)
867*0b57cec5SDimitry Andric     return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
868*0b57cec5SDimitry Andric                  "than zero");
869*0b57cec5SDimitry Andric 
870*0b57cec5SDimitry Andric   if (!Sym->isUndefined())
871*0b57cec5SDimitry Andric     return Error(IDLoc, "invalid symbol redefinition");
872*0b57cec5SDimitry Andric 
873*0b57cec5SDimitry Andric   getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
874*0b57cec5SDimitry Andric                                  "__DATA", "__thread_bss",
875*0b57cec5SDimitry Andric                                  MachO::S_THREAD_LOCAL_ZEROFILL,
876*0b57cec5SDimitry Andric                                  0, SectionKind::getThreadBSS()),
877*0b57cec5SDimitry Andric                                Sym, Size, 1 << Pow2Alignment);
878*0b57cec5SDimitry Andric 
879*0b57cec5SDimitry Andric   return false;
880*0b57cec5SDimitry Andric }
881*0b57cec5SDimitry Andric 
882*0b57cec5SDimitry Andric /// ParseDirectiveZerofill
883*0b57cec5SDimitry Andric ///  ::= .zerofill segname , sectname [, identifier , size_expression [
884*0b57cec5SDimitry Andric ///      , align_expression ]]
885*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
886*0b57cec5SDimitry Andric   StringRef Segment;
887*0b57cec5SDimitry Andric   if (getParser().parseIdentifier(Segment))
888*0b57cec5SDimitry Andric     return TokError("expected segment name after '.zerofill' directive");
889*0b57cec5SDimitry Andric 
890*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
891*0b57cec5SDimitry Andric     return TokError("unexpected token in directive");
892*0b57cec5SDimitry Andric   Lex();
893*0b57cec5SDimitry Andric 
894*0b57cec5SDimitry Andric   StringRef Section;
895*0b57cec5SDimitry Andric   SMLoc SectionLoc = getLexer().getLoc();
896*0b57cec5SDimitry Andric   if (getParser().parseIdentifier(Section))
897*0b57cec5SDimitry Andric     return TokError("expected section name after comma in '.zerofill' "
898*0b57cec5SDimitry Andric                     "directive");
899*0b57cec5SDimitry Andric 
900*0b57cec5SDimitry Andric   // If this is the end of the line all that was wanted was to create the
901*0b57cec5SDimitry Andric   // the section but with no symbol.
902*0b57cec5SDimitry Andric   if (getLexer().is(AsmToken::EndOfStatement)) {
903*0b57cec5SDimitry Andric     // Create the zerofill section but no symbol
904*0b57cec5SDimitry Andric     getStreamer().EmitZerofill(
905*0b57cec5SDimitry Andric         getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,
906*0b57cec5SDimitry Andric                                      SectionKind::getBSS()),
907*0b57cec5SDimitry Andric         /*Symbol=*/nullptr, /*Size=*/0, /*ByteAlignment=*/0, SectionLoc);
908*0b57cec5SDimitry Andric     return false;
909*0b57cec5SDimitry Andric   }
910*0b57cec5SDimitry Andric 
911*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
912*0b57cec5SDimitry Andric     return TokError("unexpected token in directive");
913*0b57cec5SDimitry Andric   Lex();
914*0b57cec5SDimitry Andric 
915*0b57cec5SDimitry Andric   SMLoc IDLoc = getLexer().getLoc();
916*0b57cec5SDimitry Andric   StringRef IDStr;
917*0b57cec5SDimitry Andric   if (getParser().parseIdentifier(IDStr))
918*0b57cec5SDimitry Andric     return TokError("expected identifier in directive");
919*0b57cec5SDimitry Andric 
920*0b57cec5SDimitry Andric   // handle the identifier as the key symbol.
921*0b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(IDStr);
922*0b57cec5SDimitry Andric 
923*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
924*0b57cec5SDimitry Andric     return TokError("unexpected token in directive");
925*0b57cec5SDimitry Andric   Lex();
926*0b57cec5SDimitry Andric 
927*0b57cec5SDimitry Andric   int64_t Size;
928*0b57cec5SDimitry Andric   SMLoc SizeLoc = getLexer().getLoc();
929*0b57cec5SDimitry Andric   if (getParser().parseAbsoluteExpression(Size))
930*0b57cec5SDimitry Andric     return true;
931*0b57cec5SDimitry Andric 
932*0b57cec5SDimitry Andric   int64_t Pow2Alignment = 0;
933*0b57cec5SDimitry Andric   SMLoc Pow2AlignmentLoc;
934*0b57cec5SDimitry Andric   if (getLexer().is(AsmToken::Comma)) {
935*0b57cec5SDimitry Andric     Lex();
936*0b57cec5SDimitry Andric     Pow2AlignmentLoc = getLexer().getLoc();
937*0b57cec5SDimitry Andric     if (getParser().parseAbsoluteExpression(Pow2Alignment))
938*0b57cec5SDimitry Andric       return true;
939*0b57cec5SDimitry Andric   }
940*0b57cec5SDimitry Andric 
941*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
942*0b57cec5SDimitry Andric     return TokError("unexpected token in '.zerofill' directive");
943*0b57cec5SDimitry Andric 
944*0b57cec5SDimitry Andric   Lex();
945*0b57cec5SDimitry Andric 
946*0b57cec5SDimitry Andric   if (Size < 0)
947*0b57cec5SDimitry Andric     return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
948*0b57cec5SDimitry Andric                  "than zero");
949*0b57cec5SDimitry Andric 
950*0b57cec5SDimitry Andric   // NOTE: The alignment in the directive is a power of 2 value, the assembler
951*0b57cec5SDimitry Andric   // may internally end up wanting an alignment in bytes.
952*0b57cec5SDimitry Andric   // FIXME: Diagnose overflow.
953*0b57cec5SDimitry Andric   if (Pow2Alignment < 0)
954*0b57cec5SDimitry Andric     return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
955*0b57cec5SDimitry Andric                  "can't be less than zero");
956*0b57cec5SDimitry Andric 
957*0b57cec5SDimitry Andric   if (!Sym->isUndefined())
958*0b57cec5SDimitry Andric     return Error(IDLoc, "invalid symbol redefinition");
959*0b57cec5SDimitry Andric 
960*0b57cec5SDimitry Andric   // Create the zerofill Symbol with Size and Pow2Alignment
961*0b57cec5SDimitry Andric   //
962*0b57cec5SDimitry Andric   // FIXME: Arch specific.
963*0b57cec5SDimitry Andric   getStreamer().EmitZerofill(getContext().getMachOSection(
964*0b57cec5SDimitry Andric                                Segment, Section, MachO::S_ZEROFILL,
965*0b57cec5SDimitry Andric                                0, SectionKind::getBSS()),
966*0b57cec5SDimitry Andric                              Sym, Size, 1 << Pow2Alignment, SectionLoc);
967*0b57cec5SDimitry Andric 
968*0b57cec5SDimitry Andric   return false;
969*0b57cec5SDimitry Andric }
970*0b57cec5SDimitry Andric 
971*0b57cec5SDimitry Andric /// ParseDirectiveDataRegion
972*0b57cec5SDimitry Andric ///  ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
973*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) {
974*0b57cec5SDimitry Andric   if (getLexer().is(AsmToken::EndOfStatement)) {
975*0b57cec5SDimitry Andric     Lex();
976*0b57cec5SDimitry Andric     getStreamer().EmitDataRegion(MCDR_DataRegion);
977*0b57cec5SDimitry Andric     return false;
978*0b57cec5SDimitry Andric   }
979*0b57cec5SDimitry Andric   StringRef RegionType;
980*0b57cec5SDimitry Andric   SMLoc Loc = getParser().getTok().getLoc();
981*0b57cec5SDimitry Andric   if (getParser().parseIdentifier(RegionType))
982*0b57cec5SDimitry Andric     return TokError("expected region type after '.data_region' directive");
983*0b57cec5SDimitry Andric   int Kind = StringSwitch<int>(RegionType)
984*0b57cec5SDimitry Andric     .Case("jt8", MCDR_DataRegionJT8)
985*0b57cec5SDimitry Andric     .Case("jt16", MCDR_DataRegionJT16)
986*0b57cec5SDimitry Andric     .Case("jt32", MCDR_DataRegionJT32)
987*0b57cec5SDimitry Andric     .Default(-1);
988*0b57cec5SDimitry Andric   if (Kind == -1)
989*0b57cec5SDimitry Andric     return Error(Loc, "unknown region type in '.data_region' directive");
990*0b57cec5SDimitry Andric   Lex();
991*0b57cec5SDimitry Andric 
992*0b57cec5SDimitry Andric   getStreamer().EmitDataRegion((MCDataRegionType)Kind);
993*0b57cec5SDimitry Andric   return false;
994*0b57cec5SDimitry Andric }
995*0b57cec5SDimitry Andric 
996*0b57cec5SDimitry Andric /// ParseDirectiveDataRegionEnd
997*0b57cec5SDimitry Andric ///  ::= .end_data_region
998*0b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
999*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
1000*0b57cec5SDimitry Andric     return TokError("unexpected token in '.end_data_region' directive");
1001*0b57cec5SDimitry Andric 
1002*0b57cec5SDimitry Andric   Lex();
1003*0b57cec5SDimitry Andric   getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
1004*0b57cec5SDimitry Andric   return false;
1005*0b57cec5SDimitry Andric }
1006*0b57cec5SDimitry Andric 
1007*0b57cec5SDimitry Andric static bool isSDKVersionToken(const AsmToken &Tok) {
1008*0b57cec5SDimitry Andric   return Tok.is(AsmToken::Identifier) && Tok.getIdentifier() == "sdk_version";
1009*0b57cec5SDimitry Andric }
1010*0b57cec5SDimitry Andric 
1011*0b57cec5SDimitry Andric /// parseMajorMinorVersionComponent ::= major, minor
1012*0b57cec5SDimitry Andric bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major,
1013*0b57cec5SDimitry Andric                                                       unsigned *Minor,
1014*0b57cec5SDimitry Andric                                                       const char *VersionName) {
1015*0b57cec5SDimitry Andric   // Get the major version number.
1016*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Integer))
1017*0b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName +
1018*0b57cec5SDimitry Andric                     " major version number, integer expected");
1019*0b57cec5SDimitry Andric   int64_t MajorVal = getLexer().getTok().getIntVal();
1020*0b57cec5SDimitry Andric   if (MajorVal > 65535 || MajorVal <= 0)
1021*0b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName + " major version number");
1022*0b57cec5SDimitry Andric   *Major = (unsigned)MajorVal;
1023*0b57cec5SDimitry Andric   Lex();
1024*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
1025*0b57cec5SDimitry Andric     return TokError(Twine(VersionName) +
1026*0b57cec5SDimitry Andric                     " minor version number required, comma expected");
1027*0b57cec5SDimitry Andric   Lex();
1028*0b57cec5SDimitry Andric   // Get the minor version number.
1029*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Integer))
1030*0b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName +
1031*0b57cec5SDimitry Andric                     " minor version number, integer expected");
1032*0b57cec5SDimitry Andric   int64_t MinorVal = getLexer().getTok().getIntVal();
1033*0b57cec5SDimitry Andric   if (MinorVal > 255 || MinorVal < 0)
1034*0b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName + " minor version number");
1035*0b57cec5SDimitry Andric   *Minor = MinorVal;
1036*0b57cec5SDimitry Andric   Lex();
1037*0b57cec5SDimitry Andric   return false;
1038*0b57cec5SDimitry Andric }
1039*0b57cec5SDimitry Andric 
1040*0b57cec5SDimitry Andric /// parseOptionalTrailingVersionComponent ::= , version_number
1041*0b57cec5SDimitry Andric bool DarwinAsmParser::parseOptionalTrailingVersionComponent(
1042*0b57cec5SDimitry Andric     unsigned *Component, const char *ComponentName) {
1043*0b57cec5SDimitry Andric   assert(getLexer().is(AsmToken::Comma) && "comma expected");
1044*0b57cec5SDimitry Andric   Lex();
1045*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Integer))
1046*0b57cec5SDimitry Andric     return TokError(Twine("invalid ") + ComponentName +
1047*0b57cec5SDimitry Andric                     " version number, integer expected");
1048*0b57cec5SDimitry Andric   int64_t Val = getLexer().getTok().getIntVal();
1049*0b57cec5SDimitry Andric   if (Val > 255 || Val < 0)
1050*0b57cec5SDimitry Andric     return TokError(Twine("invalid ") + ComponentName + " version number");
1051*0b57cec5SDimitry Andric   *Component = Val;
1052*0b57cec5SDimitry Andric   Lex();
1053*0b57cec5SDimitry Andric   return false;
1054*0b57cec5SDimitry Andric }
1055*0b57cec5SDimitry Andric 
1056*0b57cec5SDimitry Andric /// parseVersion ::= parseMajorMinorVersionComponent
1057*0b57cec5SDimitry Andric ///                      parseOptionalTrailingVersionComponent
1058*0b57cec5SDimitry Andric bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor,
1059*0b57cec5SDimitry Andric                                    unsigned *Update) {
1060*0b57cec5SDimitry Andric   if (parseMajorMinorVersionComponent(Major, Minor, "OS"))
1061*0b57cec5SDimitry Andric     return true;
1062*0b57cec5SDimitry Andric 
1063*0b57cec5SDimitry Andric   // Get the update level, if specified
1064*0b57cec5SDimitry Andric   *Update = 0;
1065*0b57cec5SDimitry Andric   if (getLexer().is(AsmToken::EndOfStatement) ||
1066*0b57cec5SDimitry Andric       isSDKVersionToken(getLexer().getTok()))
1067*0b57cec5SDimitry Andric     return false;
1068*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
1069*0b57cec5SDimitry Andric     return TokError("invalid OS update specifier, comma expected");
1070*0b57cec5SDimitry Andric   if (parseOptionalTrailingVersionComponent(Update, "OS update"))
1071*0b57cec5SDimitry Andric     return true;
1072*0b57cec5SDimitry Andric   return false;
1073*0b57cec5SDimitry Andric }
1074*0b57cec5SDimitry Andric 
1075*0b57cec5SDimitry Andric bool DarwinAsmParser::parseSDKVersion(VersionTuple &SDKVersion) {
1076*0b57cec5SDimitry Andric   assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version");
1077*0b57cec5SDimitry Andric   Lex();
1078*0b57cec5SDimitry Andric   unsigned Major, Minor;
1079*0b57cec5SDimitry Andric   if (parseMajorMinorVersionComponent(&Major, &Minor, "SDK"))
1080*0b57cec5SDimitry Andric     return true;
1081*0b57cec5SDimitry Andric   SDKVersion = VersionTuple(Major, Minor);
1082*0b57cec5SDimitry Andric 
1083*0b57cec5SDimitry Andric   // Get the subminor version, if specified.
1084*0b57cec5SDimitry Andric   if (getLexer().is(AsmToken::Comma)) {
1085*0b57cec5SDimitry Andric     unsigned Subminor;
1086*0b57cec5SDimitry Andric     if (parseOptionalTrailingVersionComponent(&Subminor, "SDK subminor"))
1087*0b57cec5SDimitry Andric       return true;
1088*0b57cec5SDimitry Andric     SDKVersion = VersionTuple(Major, Minor, Subminor);
1089*0b57cec5SDimitry Andric   }
1090*0b57cec5SDimitry Andric   return false;
1091*0b57cec5SDimitry Andric }
1092*0b57cec5SDimitry Andric 
1093*0b57cec5SDimitry Andric void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg,
1094*0b57cec5SDimitry Andric                                    SMLoc Loc, Triple::OSType ExpectedOS) {
1095*0b57cec5SDimitry Andric   const Triple &Target = getContext().getObjectFileInfo()->getTargetTriple();
1096*0b57cec5SDimitry Andric   if (Target.getOS() != ExpectedOS)
1097*0b57cec5SDimitry Andric     Warning(Loc, Twine(Directive) +
1098*0b57cec5SDimitry Andric             (Arg.empty() ? Twine() : Twine(' ') + Arg) +
1099*0b57cec5SDimitry Andric             " used while targeting " + Target.getOSName());
1100*0b57cec5SDimitry Andric 
1101*0b57cec5SDimitry Andric   if (LastVersionDirective.isValid()) {
1102*0b57cec5SDimitry Andric     Warning(Loc, "overriding previous version directive");
1103*0b57cec5SDimitry Andric     Note(LastVersionDirective, "previous definition is here");
1104*0b57cec5SDimitry Andric   }
1105*0b57cec5SDimitry Andric   LastVersionDirective = Loc;
1106*0b57cec5SDimitry Andric }
1107*0b57cec5SDimitry Andric 
1108*0b57cec5SDimitry Andric static Triple::OSType getOSTypeFromMCVM(MCVersionMinType Type) {
1109*0b57cec5SDimitry Andric   switch (Type) {
1110*0b57cec5SDimitry Andric   case MCVM_WatchOSVersionMin: return Triple::WatchOS;
1111*0b57cec5SDimitry Andric   case MCVM_TvOSVersionMin:    return Triple::TvOS;
1112*0b57cec5SDimitry Andric   case MCVM_IOSVersionMin:     return Triple::IOS;
1113*0b57cec5SDimitry Andric   case MCVM_OSXVersionMin:     return Triple::MacOSX;
1114*0b57cec5SDimitry Andric   }
1115*0b57cec5SDimitry Andric   llvm_unreachable("Invalid mc version min type");
1116*0b57cec5SDimitry Andric }
1117*0b57cec5SDimitry Andric 
1118*0b57cec5SDimitry Andric /// parseVersionMin
1119*0b57cec5SDimitry Andric ///   ::= .ios_version_min parseVersion parseSDKVersion
1120*0b57cec5SDimitry Andric ///   |   .macosx_version_min parseVersion parseSDKVersion
1121*0b57cec5SDimitry Andric ///   |   .tvos_version_min parseVersion parseSDKVersion
1122*0b57cec5SDimitry Andric ///   |   .watchos_version_min parseVersion parseSDKVersion
1123*0b57cec5SDimitry Andric bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc,
1124*0b57cec5SDimitry Andric                                       MCVersionMinType Type) {
1125*0b57cec5SDimitry Andric   unsigned Major;
1126*0b57cec5SDimitry Andric   unsigned Minor;
1127*0b57cec5SDimitry Andric   unsigned Update;
1128*0b57cec5SDimitry Andric   if (parseVersion(&Major, &Minor, &Update))
1129*0b57cec5SDimitry Andric     return true;
1130*0b57cec5SDimitry Andric 
1131*0b57cec5SDimitry Andric   VersionTuple SDKVersion;
1132*0b57cec5SDimitry Andric   if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
1133*0b57cec5SDimitry Andric     return true;
1134*0b57cec5SDimitry Andric 
1135*0b57cec5SDimitry Andric   if (parseToken(AsmToken::EndOfStatement))
1136*0b57cec5SDimitry Andric     return addErrorSuffix(Twine(" in '") + Directive + "' directive");
1137*0b57cec5SDimitry Andric 
1138*0b57cec5SDimitry Andric   Triple::OSType ExpectedOS = getOSTypeFromMCVM(Type);
1139*0b57cec5SDimitry Andric   checkVersion(Directive, StringRef(), Loc, ExpectedOS);
1140*0b57cec5SDimitry Andric   getStreamer().EmitVersionMin(Type, Major, Minor, Update, SDKVersion);
1141*0b57cec5SDimitry Andric   return false;
1142*0b57cec5SDimitry Andric }
1143*0b57cec5SDimitry Andric 
1144*0b57cec5SDimitry Andric static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) {
1145*0b57cec5SDimitry Andric   switch (Type) {
1146*0b57cec5SDimitry Andric   case MachO::PLATFORM_MACOS:   return Triple::MacOSX;
1147*0b57cec5SDimitry Andric   case MachO::PLATFORM_IOS:     return Triple::IOS;
1148*0b57cec5SDimitry Andric   case MachO::PLATFORM_TVOS:    return Triple::TvOS;
1149*0b57cec5SDimitry Andric   case MachO::PLATFORM_WATCHOS: return Triple::WatchOS;
1150*0b57cec5SDimitry Andric   case MachO::PLATFORM_BRIDGEOS:         /* silence warning */ break;
1151*0b57cec5SDimitry Andric   case MachO::PLATFORM_MACCATALYST: return Triple::IOS;
1152*0b57cec5SDimitry Andric   case MachO::PLATFORM_IOSSIMULATOR:     /* silence warning */ break;
1153*0b57cec5SDimitry Andric   case MachO::PLATFORM_TVOSSIMULATOR:    /* silence warning */ break;
1154*0b57cec5SDimitry Andric   case MachO::PLATFORM_WATCHOSSIMULATOR: /* silence warning */ break;
1155*0b57cec5SDimitry Andric   }
1156*0b57cec5SDimitry Andric   llvm_unreachable("Invalid mach-o platform type");
1157*0b57cec5SDimitry Andric }
1158*0b57cec5SDimitry Andric 
1159*0b57cec5SDimitry Andric /// parseBuildVersion
1160*0b57cec5SDimitry Andric ///   ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion
1161*0b57cec5SDimitry Andric bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {
1162*0b57cec5SDimitry Andric   StringRef PlatformName;
1163*0b57cec5SDimitry Andric   SMLoc PlatformLoc = getTok().getLoc();
1164*0b57cec5SDimitry Andric   if (getParser().parseIdentifier(PlatformName))
1165*0b57cec5SDimitry Andric     return TokError("platform name expected");
1166*0b57cec5SDimitry Andric 
1167*0b57cec5SDimitry Andric   unsigned Platform = StringSwitch<unsigned>(PlatformName)
1168*0b57cec5SDimitry Andric     .Case("macos", MachO::PLATFORM_MACOS)
1169*0b57cec5SDimitry Andric     .Case("ios", MachO::PLATFORM_IOS)
1170*0b57cec5SDimitry Andric     .Case("tvos", MachO::PLATFORM_TVOS)
1171*0b57cec5SDimitry Andric     .Case("watchos", MachO::PLATFORM_WATCHOS)
1172*0b57cec5SDimitry Andric     .Case("macCatalyst", MachO::PLATFORM_MACCATALYST)
1173*0b57cec5SDimitry Andric     .Default(0);
1174*0b57cec5SDimitry Andric   if (Platform == 0)
1175*0b57cec5SDimitry Andric     return Error(PlatformLoc, "unknown platform name");
1176*0b57cec5SDimitry Andric 
1177*0b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
1178*0b57cec5SDimitry Andric     return TokError("version number required, comma expected");
1179*0b57cec5SDimitry Andric   Lex();
1180*0b57cec5SDimitry Andric 
1181*0b57cec5SDimitry Andric   unsigned Major;
1182*0b57cec5SDimitry Andric   unsigned Minor;
1183*0b57cec5SDimitry Andric   unsigned Update;
1184*0b57cec5SDimitry Andric   if (parseVersion(&Major, &Minor, &Update))
1185*0b57cec5SDimitry Andric     return true;
1186*0b57cec5SDimitry Andric 
1187*0b57cec5SDimitry Andric   VersionTuple SDKVersion;
1188*0b57cec5SDimitry Andric   if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
1189*0b57cec5SDimitry Andric     return true;
1190*0b57cec5SDimitry Andric 
1191*0b57cec5SDimitry Andric   if (parseToken(AsmToken::EndOfStatement))
1192*0b57cec5SDimitry Andric     return addErrorSuffix(" in '.build_version' directive");
1193*0b57cec5SDimitry Andric 
1194*0b57cec5SDimitry Andric   Triple::OSType ExpectedOS
1195*0b57cec5SDimitry Andric     = getOSTypeFromPlatform((MachO::PlatformType)Platform);
1196*0b57cec5SDimitry Andric   checkVersion(Directive, PlatformName, Loc, ExpectedOS);
1197*0b57cec5SDimitry Andric   getStreamer().EmitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
1198*0b57cec5SDimitry Andric   return false;
1199*0b57cec5SDimitry Andric }
1200*0b57cec5SDimitry Andric 
1201*0b57cec5SDimitry Andric 
1202*0b57cec5SDimitry Andric namespace llvm {
1203*0b57cec5SDimitry Andric 
1204*0b57cec5SDimitry Andric MCAsmParserExtension *createDarwinAsmParser() {
1205*0b57cec5SDimitry Andric   return new DarwinAsmParser;
1206*0b57cec5SDimitry Andric }
1207*0b57cec5SDimitry Andric 
1208*0b57cec5SDimitry Andric } // end llvm namespace
1209