blob: f08270c15287eafbdf7289c0f4eb7dd230e18964 [file] [log] [blame]
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +00001//===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/MC/MCParser/MCAsmParserExtension.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000011#include "llvm/ADT/StringRef.h"
12#include "llvm/ADT/StringSwitch.h"
13#include "llvm/ADT/Twine.h"
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000014#include "llvm/MC/MCContext.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000015#include "llvm/MC/MCParser/MCAsmLexer.h"
16#include "llvm/MC/MCParser/MCAsmParser.h"
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000017#include "llvm/MC/MCSectionMachO.h"
18#include "llvm/MC/MCStreamer.h"
19#include "llvm/MC/MCSymbol.h"
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000020#include "llvm/Support/MemoryBuffer.h"
21#include "llvm/Support/SourceMgr.h"
22using namespace llvm;
23
24namespace {
25
26/// \brief Implementation of directive handling which is shared across all
27/// Darwin targets.
28class DarwinAsmParser : public MCAsmParserExtension {
Eli Bendersky171192f2013-01-16 00:50:52 +000029 template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000030 void addDirectiveHandler(StringRef Directive) {
Eli Bendersky171192f2013-01-16 00:50:52 +000031 MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
32 this, HandleDirective<DarwinAsmParser, HandlerMethod>);
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000033 getParser().addDirectiveHandler(Directive, Handler);
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000034 }
35
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000036 bool ParseSectionSwitch(const char *Segment, const char *Section,
37 unsigned TAA = 0, unsigned ImplicitAlign = 0,
38 unsigned StubSize = 0);
39
40public:
41 DarwinAsmParser() {}
42
43 virtual void Initialize(MCAsmParser &Parser) {
44 // Call the base implementation.
45 this->MCAsmParserExtension::Initialize(Parser);
46
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000047 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
Kevin Enderby4f066b62013-08-28 17:50:59 +000048 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveIndirectSymbol>(
49 ".indirect_symbol");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000050 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
51 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000052 ".subsections_via_symbols");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000053 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
54 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
55 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
56 addDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000057 ".pushsection");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000058 addDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000059 ".popsection");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000060 addDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
61 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000062 ".secure_log_unique");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000063 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000064 ".secure_log_reset");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000065 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
66 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000067
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000068 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000069 ".data_region");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000070 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000071 ".end_data_region");
Jim Grosbach3e965312012-05-18 19:12:01 +000072
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000073 // Special section directives.
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000074 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
75 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000076 ".const_data");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000077 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000078 ".constructor");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000079 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000080 ".cstring");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000081 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
82 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000083 ".destructor");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000084 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
85 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000086 ".fvmlib_init0");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000087 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000088 ".fvmlib_init1");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000089 addDirectiveHandler<
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000090 &DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(
91 ".lazy_symbol_pointer");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000092 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLinkerOption>(
Daniel Dunbarcddd2362013-01-18 01:25:48 +000093 ".linker_option");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000094 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000095 ".literal16");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000096 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000097 ".literal4");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +000098 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000099 ".literal8");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000100 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000101 ".mod_init_func");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000102 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000103 ".mod_term_func");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000104 addDirectiveHandler<
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000105 &DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(
106 ".non_lazy_symbol_pointer");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000107 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000108 ".objc_cat_cls_meth");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000109 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000110 ".objc_cat_inst_meth");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000111 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000112 ".objc_category");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000113 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000114 ".objc_class");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000115 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000116 ".objc_class_names");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000117 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000118 ".objc_class_vars");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000119 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000120 ".objc_cls_meth");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000121 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000122 ".objc_cls_refs");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000123 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000124 ".objc_inst_meth");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000125 addDirectiveHandler<
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000126 &DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(
127 ".objc_instance_vars");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000128 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000129 ".objc_message_refs");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000130 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000131 ".objc_meta_class");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000132 addDirectiveHandler<
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000133 &DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(
134 ".objc_meth_var_names");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000135 addDirectiveHandler<
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000136 &DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(
137 ".objc_meth_var_types");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000138 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000139 ".objc_module_info");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000140 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000141 ".objc_protocol");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000142 addDirectiveHandler<
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000143 &DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(
144 ".objc_selector_strs");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000145 addDirectiveHandler<
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000146 &DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(
147 ".objc_string_object");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000148 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000149 ".objc_symbols");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000150 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000151 ".picsymbol_stub");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000152 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000153 ".static_const");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000154 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000155 ".static_data");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000156 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000157 ".symbol_stub");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000158 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
159 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
160 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000161 ".thread_init_func");
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000162 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
Jim Grosbach8270da82011-03-08 19:17:19 +0000163
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000164 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000165 }
166
167 bool ParseDirectiveDesc(StringRef, SMLoc);
Kevin Enderby4f066b62013-08-28 17:50:59 +0000168 bool ParseDirectiveIndirectSymbol(StringRef, SMLoc);
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000169 bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
170 bool ParseDirectiveLsym(StringRef, SMLoc);
Daniel Dunbarcddd2362013-01-18 01:25:48 +0000171 bool ParseDirectiveLinkerOption(StringRef, SMLoc);
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +0000172 bool ParseDirectiveSection(StringRef, SMLoc);
Bill Wendlingef920552012-08-08 06:30:30 +0000173 bool ParseDirectivePushSection(StringRef, SMLoc);
174 bool ParseDirectivePopSection(StringRef, SMLoc);
175 bool ParseDirectivePrevious(StringRef, SMLoc);
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000176 bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
177 bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
178 bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
179 bool ParseDirectiveTBSS(StringRef, SMLoc);
180 bool ParseDirectiveZerofill(StringRef, SMLoc);
Jim Grosbach3e965312012-05-18 19:12:01 +0000181 bool ParseDirectiveDataRegion(StringRef, SMLoc);
182 bool ParseDirectiveDataRegionEnd(StringRef, SMLoc);
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000183
184 // Named Section Directive
185 bool ParseSectionDirectiveConst(StringRef, SMLoc) {
186 return ParseSectionSwitch("__TEXT", "__const");
187 }
188 bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) {
189 return ParseSectionSwitch("__TEXT", "__static_const");
190 }
191 bool ParseSectionDirectiveCString(StringRef, SMLoc) {
192 return ParseSectionSwitch("__TEXT","__cstring",
193 MCSectionMachO::S_CSTRING_LITERALS);
194 }
195 bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) {
196 return ParseSectionSwitch("__TEXT", "__literal4",
197 MCSectionMachO::S_4BYTE_LITERALS, 4);
198 }
199 bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) {
200 return ParseSectionSwitch("__TEXT", "__literal8",
201 MCSectionMachO::S_8BYTE_LITERALS, 8);
202 }
203 bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) {
204 return ParseSectionSwitch("__TEXT","__literal16",
205 MCSectionMachO::S_16BYTE_LITERALS, 16);
206 }
207 bool ParseSectionDirectiveConstructor(StringRef, SMLoc) {
208 return ParseSectionSwitch("__TEXT","__constructor");
209 }
210 bool ParseSectionDirectiveDestructor(StringRef, SMLoc) {
211 return ParseSectionSwitch("__TEXT","__destructor");
212 }
213 bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
214 return ParseSectionSwitch("__TEXT","__fvmlib_init0");
215 }
216 bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
217 return ParseSectionSwitch("__TEXT","__fvmlib_init1");
218 }
219 bool ParseSectionDirectiveSymbolStub(StringRef, SMLoc) {
220 return ParseSectionSwitch("__TEXT","__symbol_stub",
221 MCSectionMachO::S_SYMBOL_STUBS |
222 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
223 // FIXME: Different on PPC and ARM.
224 0, 16);
225 }
226 bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
227 return ParseSectionSwitch("__TEXT","__picsymbol_stub",
228 MCSectionMachO::S_SYMBOL_STUBS |
229 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
230 }
231 bool ParseSectionDirectiveData(StringRef, SMLoc) {
232 return ParseSectionSwitch("__DATA", "__data");
233 }
234 bool ParseSectionDirectiveStaticData(StringRef, SMLoc) {
235 return ParseSectionSwitch("__DATA", "__static_data");
236 }
237 bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
238 return ParseSectionSwitch("__DATA", "__nl_symbol_ptr",
239 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
240 }
241 bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
242 return ParseSectionSwitch("__DATA", "__la_symbol_ptr",
243 MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 4);
244 }
245 bool ParseSectionDirectiveDyld(StringRef, SMLoc) {
246 return ParseSectionSwitch("__DATA", "__dyld");
247 }
248 bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) {
249 return ParseSectionSwitch("__DATA", "__mod_init_func",
250 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 4);
251 }
252 bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) {
253 return ParseSectionSwitch("__DATA", "__mod_term_func",
254 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 4);
255 }
256 bool ParseSectionDirectiveConstData(StringRef, SMLoc) {
257 return ParseSectionSwitch("__DATA", "__const");
258 }
259 bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) {
260 return ParseSectionSwitch("__OBJC", "__class",
261 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
262 }
263 bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
264 return ParseSectionSwitch("__OBJC", "__meta_class",
265 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
266 }
267 bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
268 return ParseSectionSwitch("__OBJC", "__cat_cls_meth",
269 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
270 }
271 bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
272 return ParseSectionSwitch("__OBJC", "__cat_inst_meth",
273 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
274 }
275 bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
276 return ParseSectionSwitch("__OBJC", "__protocol",
277 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
278 }
279 bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
280 return ParseSectionSwitch("__OBJC", "__string_object",
281 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
282 }
283 bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
284 return ParseSectionSwitch("__OBJC", "__cls_meth",
285 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
286 }
287 bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
288 return ParseSectionSwitch("__OBJC", "__inst_meth",
289 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
290 }
291 bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
292 return ParseSectionSwitch("__OBJC", "__cls_refs",
293 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
294 MCSectionMachO::S_LITERAL_POINTERS, 4);
295 }
296 bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
297 return ParseSectionSwitch("__OBJC", "__message_refs",
298 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
299 MCSectionMachO::S_LITERAL_POINTERS, 4);
300 }
301 bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
302 return ParseSectionSwitch("__OBJC", "__symbols",
303 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
304 }
305 bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) {
306 return ParseSectionSwitch("__OBJC", "__category",
307 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
308 }
309 bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
310 return ParseSectionSwitch("__OBJC", "__class_vars",
311 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
312 }
313 bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
314 return ParseSectionSwitch("__OBJC", "__instance_vars",
315 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
316 }
317 bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
318 return ParseSectionSwitch("__OBJC", "__module_info",
319 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
320 }
321 bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
322 return ParseSectionSwitch("__TEXT", "__cstring",
323 MCSectionMachO::S_CSTRING_LITERALS);
324 }
325 bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
326 return ParseSectionSwitch("__TEXT", "__cstring",
327 MCSectionMachO::S_CSTRING_LITERALS);
328 }
329 bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
330 return ParseSectionSwitch("__TEXT", "__cstring",
331 MCSectionMachO::S_CSTRING_LITERALS);
332 }
333 bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
334 return ParseSectionSwitch("__OBJC", "__selector_strs",
335 MCSectionMachO::S_CSTRING_LITERALS);
336 }
337 bool ParseSectionDirectiveTData(StringRef, SMLoc) {
338 return ParseSectionSwitch("__DATA", "__thread_data",
339 MCSectionMachO::S_THREAD_LOCAL_REGULAR);
340 }
341 bool ParseSectionDirectiveText(StringRef, SMLoc) {
342 return ParseSectionSwitch("__TEXT", "__text",
343 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
344 }
345 bool ParseSectionDirectiveTLV(StringRef, SMLoc) {
346 return ParseSectionSwitch("__DATA", "__thread_vars",
347 MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
348 }
Jim Grosbach8270da82011-03-08 19:17:19 +0000349 bool ParseSectionDirectiveIdent(StringRef, SMLoc) {
350 // Darwin silently ignores the .ident directive.
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000351 getParser().eatToEndOfStatement();
Jim Grosbach8270da82011-03-08 19:17:19 +0000352 return false;
353 }
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000354 bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
355 return ParseSectionSwitch("__DATA", "__thread_init",
356 MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
357 }
358
359};
360
Bill Wendlingef920552012-08-08 06:30:30 +0000361} // end anonymous namespace
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000362
363bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
364 const char *Section,
365 unsigned TAA, unsigned Align,
366 unsigned StubSize) {
367 if (getLexer().isNot(AsmToken::EndOfStatement))
368 return TokError("unexpected token in section switching directive");
369 Lex();
370
371 // FIXME: Arch specific.
Tim Northover1c2b2f92012-12-17 17:59:32 +0000372 bool isText = TAA & MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS;
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000373 getStreamer().SwitchSection(getContext().getMachOSection(
374 Segment, Section, TAA, StubSize,
375 isText ? SectionKind::getText()
376 : SectionKind::getDataRel()));
377
378 // Set the implicit alignment, if any.
379 //
380 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
381 // alignment on the section (e.g., if one manually inserts bytes into the
Bill Wendlingcf2561d2010-10-19 10:18:23 +0000382 // section, then just issuing the section switch directive will not realign
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000383 // the section. However, this is arguably more reasonable behavior, and there
384 // is no good reason for someone to intentionally emit incorrectly sized
385 // values into the implicitly aligned sections.
386 if (Align)
387 getStreamer().EmitValueToAlignment(Align, 0, 1, 0);
388
389 return false;
390}
391
392/// ParseDirectiveDesc
393/// ::= .desc identifier , expression
394bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
395 StringRef Name;
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000396 if (getParser().parseIdentifier(Name))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000397 return TokError("expected identifier in directive");
398
399 // Handle the identifier as the key symbol.
400 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
401
402 if (getLexer().isNot(AsmToken::Comma))
403 return TokError("unexpected token in '.desc' directive");
404 Lex();
405
406 int64_t DescValue;
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000407 if (getParser().parseAbsoluteExpression(DescValue))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000408 return true;
409
410 if (getLexer().isNot(AsmToken::EndOfStatement))
411 return TokError("unexpected token in '.desc' directive");
412
413 Lex();
414
415 // Set the n_desc field of this Symbol to this DescValue
416 getStreamer().EmitSymbolDesc(Sym, DescValue);
417
418 return false;
419}
420
Kevin Enderby4f066b62013-08-28 17:50:59 +0000421/// ParseDirectiveIndirectSymbol
422/// ::= .indirect_symbol identifier
423bool DarwinAsmParser::ParseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
424 const MCSectionMachO *Current = static_cast<const MCSectionMachO*>(
425 getStreamer().getCurrentSection().first);
426 unsigned SectionType = Current->getType();
427 if (SectionType != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS &&
428 SectionType != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
429 SectionType != MCSectionMachO::S_SYMBOL_STUBS)
430 return Error(Loc, "indirect symbol not in a symbol pointer or stub "
431 "section");
432
433 StringRef Name;
434 if (getParser().parseIdentifier(Name))
435 return TokError("expected identifier in .indirect_symbol directive");
436
437 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
438
439 // Assembler local symbols don't make any sense here. Complain loudly.
440 if (Sym->isTemporary())
441 return TokError("non-local symbol required in directive");
442
443 if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol))
444 return TokError("unable to emit indirect symbol attribute for: " + Name);
445
446 if (getLexer().isNot(AsmToken::EndOfStatement))
447 return TokError("unexpected token in '.indirect_symbol' directive");
448
449 Lex();
450
451 return false;
452}
453
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000454/// ParseDirectiveDumpOrLoad
455/// ::= ( .dump | .load ) "filename"
456bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
457 SMLoc IDLoc) {
458 bool IsDump = Directive == ".dump";
459 if (getLexer().isNot(AsmToken::String))
460 return TokError("expected string in '.dump' or '.load' directive");
461
462 Lex();
463
464 if (getLexer().isNot(AsmToken::EndOfStatement))
465 return TokError("unexpected token in '.dump' or '.load' directive");
466
467 Lex();
468
469 // FIXME: If/when .dump and .load are implemented they will be done in the
470 // the assembly parser and not have any need for an MCStreamer API.
471 if (IsDump)
Joerg Sonnenbergerf8cd7082011-05-19 18:00:13 +0000472 return Warning(IDLoc, "ignoring directive .dump for now");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000473 else
Joerg Sonnenbergerf8cd7082011-05-19 18:00:13 +0000474 return Warning(IDLoc, "ignoring directive .load for now");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000475}
476
Daniel Dunbarcddd2362013-01-18 01:25:48 +0000477/// ParseDirectiveLinkerOption
478/// ::= .linker_option "string" ( , "string" )*
479bool DarwinAsmParser::ParseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
480 SmallVector<std::string, 4> Args;
481 for (;;) {
482 if (getLexer().isNot(AsmToken::String))
483 return TokError("expected string in '" + Twine(IDVal) + "' directive");
484
485 std::string Data;
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000486 if (getParser().parseEscapedString(Data))
Daniel Dunbarcddd2362013-01-18 01:25:48 +0000487 return true;
488
489 Args.push_back(Data);
490
491 Lex();
492 if (getLexer().is(AsmToken::EndOfStatement))
493 break;
494
495 if (getLexer().isNot(AsmToken::Comma))
496 return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
497 Lex();
498 }
499
500 getStreamer().EmitLinkerOptions(Args);
501 return false;
502}
503
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000504/// ParseDirectiveLsym
505/// ::= .lsym identifier , expression
506bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
507 StringRef Name;
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000508 if (getParser().parseIdentifier(Name))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000509 return TokError("expected identifier in directive");
510
511 // Handle the identifier as the key symbol.
512 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
513
514 if (getLexer().isNot(AsmToken::Comma))
515 return TokError("unexpected token in '.lsym' directive");
516 Lex();
517
518 const MCExpr *Value;
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000519 if (getParser().parseExpression(Value))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000520 return true;
521
522 if (getLexer().isNot(AsmToken::EndOfStatement))
523 return TokError("unexpected token in '.lsym' directive");
524
525 Lex();
526
527 // We don't currently support this directive.
528 //
529 // FIXME: Diagnostic location!
530 (void) Sym;
531 return TokError("directive '.lsym' is unsupported");
532}
533
534/// ParseDirectiveSection:
535/// ::= .section identifier (',' identifier)*
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +0000536bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000537 SMLoc Loc = getLexer().getLoc();
538
539 StringRef SectionName;
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000540 if (getParser().parseIdentifier(SectionName))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000541 return Error(Loc, "expected identifier after '.section' directive");
542
543 // Verify there is a following comma.
544 if (!getLexer().is(AsmToken::Comma))
545 return TokError("unexpected token in '.section' directive");
546
547 std::string SectionSpec = SectionName;
548 SectionSpec += ",";
549
550 // Add all the tokens until the end of the line, ParseSectionSpecifier will
551 // handle this.
552 StringRef EOL = getLexer().LexUntilEndOfStatement();
553 SectionSpec.append(EOL.begin(), EOL.end());
554
555 Lex();
556 if (getLexer().isNot(AsmToken::EndOfStatement))
557 return TokError("unexpected token in '.section' directive");
558 Lex();
559
560
561 StringRef Segment, Section;
Daniel Dunbar8d06ffc2011-03-17 16:25:24 +0000562 unsigned StubSize;
Stuart Hastings65c8bca2011-03-19 02:42:31 +0000563 unsigned TAA;
564 bool TAAParsed;
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000565 std::string ErrorStr =
566 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
Stuart Hastings65c8bca2011-03-19 02:42:31 +0000567 TAA, TAAParsed, StubSize);
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000568
569 if (!ErrorStr.empty())
570 return Error(Loc, ErrorStr.c_str());
571
572 // FIXME: Arch specific.
573 bool isText = Segment == "__TEXT"; // FIXME: Hack.
574 getStreamer().SwitchSection(getContext().getMachOSection(
575 Segment, Section, TAA, StubSize,
576 isText ? SectionKind::getText()
577 : SectionKind::getDataRel()));
578 return false;
579}
580
Bill Wendlingef920552012-08-08 06:30:30 +0000581/// ParseDirectivePushSection:
582/// ::= .pushsection identifier (',' identifier)*
583bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
584 getStreamer().PushSection();
585
586 if (ParseDirectiveSection(S, Loc)) {
587 getStreamer().PopSection();
588 return true;
589 }
590
591 return false;
592}
593
594/// ParseDirectivePopSection:
595/// ::= .popsection
596bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
597 if (!getStreamer().PopSection())
598 return TokError(".popsection without corresponding .pushsection");
599 return false;
600}
601
602/// ParseDirectivePrevious:
603/// ::= .previous
604bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
Peter Collingbournedf39be62013-04-17 21:18:16 +0000605 MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
606 if (PreviousSection.first == NULL)
Bill Wendlingef920552012-08-08 06:30:30 +0000607 return TokError(".previous without corresponding .section");
Peter Collingbournedf39be62013-04-17 21:18:16 +0000608 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
Bill Wendlingef920552012-08-08 06:30:30 +0000609 return false;
610}
611
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000612/// ParseDirectiveSecureLogUnique
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000613/// ::= .secure_log_unique ... message ...
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000614bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000615 StringRef LogMessage = getParser().parseStringToEndOfStatement();
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000616 if (getLexer().isNot(AsmToken::EndOfStatement))
617 return TokError("unexpected token in '.secure_log_unique' directive");
618
619 if (getContext().getSecureLogUsed() != false)
620 return Error(IDLoc, ".secure_log_unique specified multiple times");
621
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000622 // Get the secure log path.
623 const char *SecureLogFile = getContext().getSecureLogFile();
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000624 if (SecureLogFile == NULL)
625 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
626 "environment variable unset.");
627
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000628 // Open the secure log file if we haven't already.
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000629 raw_ostream *OS = getContext().getSecureLog();
630 if (OS == NULL) {
631 std::string Err;
Rafael Espindolac1b49b52013-07-16 19:44:17 +0000632 OS = new raw_fd_ostream(SecureLogFile, Err, sys::fs::F_Append);
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000633 if (!Err.empty()) {
634 delete OS;
635 return Error(IDLoc, Twine("can't open secure log file: ") +
636 SecureLogFile + " (" + Err + ")");
637 }
638 getContext().setSecureLog(OS);
639 }
640
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000641 // Write the message.
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000642 int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
643 *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
644 << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
645 << LogMessage + "\n";
646
647 getContext().setSecureLogUsed(true);
648
649 return false;
650}
651
652/// ParseDirectiveSecureLogReset
653/// ::= .secure_log_reset
654bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
655 if (getLexer().isNot(AsmToken::EndOfStatement))
656 return TokError("unexpected token in '.secure_log_reset' directive");
657
658 Lex();
659
660 getContext().setSecureLogUsed(false);
661
662 return false;
663}
664
665/// ParseDirectiveSubsectionsViaSymbols
666/// ::= .subsections_via_symbols
667bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
668 if (getLexer().isNot(AsmToken::EndOfStatement))
669 return TokError("unexpected token in '.subsections_via_symbols' directive");
670
671 Lex();
672
673 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
674
675 return false;
676}
677
678/// ParseDirectiveTBSS
679/// ::= .tbss identifier, size, align
680bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
681 SMLoc IDLoc = getLexer().getLoc();
682 StringRef Name;
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000683 if (getParser().parseIdentifier(Name))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000684 return TokError("expected identifier in directive");
685
686 // Handle the identifier as the key symbol.
687 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
688
689 if (getLexer().isNot(AsmToken::Comma))
690 return TokError("unexpected token in directive");
691 Lex();
692
693 int64_t Size;
694 SMLoc SizeLoc = getLexer().getLoc();
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000695 if (getParser().parseAbsoluteExpression(Size))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000696 return true;
697
698 int64_t Pow2Alignment = 0;
699 SMLoc Pow2AlignmentLoc;
700 if (getLexer().is(AsmToken::Comma)) {
701 Lex();
702 Pow2AlignmentLoc = getLexer().getLoc();
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000703 if (getParser().parseAbsoluteExpression(Pow2Alignment))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000704 return true;
705 }
706
707 if (getLexer().isNot(AsmToken::EndOfStatement))
708 return TokError("unexpected token in '.tbss' directive");
709
710 Lex();
711
712 if (Size < 0)
713 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
714 "zero");
715
716 // FIXME: Diagnose overflow.
717 if (Pow2Alignment < 0)
718 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
719 "than zero");
720
721 if (!Sym->isUndefined())
722 return Error(IDLoc, "invalid symbol redefinition");
723
724 getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
725 "__DATA", "__thread_bss",
726 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
727 0, SectionKind::getThreadBSS()),
728 Sym, Size, 1 << Pow2Alignment);
729
730 return false;
731}
732
733/// ParseDirectiveZerofill
734/// ::= .zerofill segname , sectname [, identifier , size_expression [
735/// , align_expression ]]
736bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
737 StringRef Segment;
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000738 if (getParser().parseIdentifier(Segment))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000739 return TokError("expected segment name after '.zerofill' directive");
740
741 if (getLexer().isNot(AsmToken::Comma))
742 return TokError("unexpected token in directive");
743 Lex();
744
745 StringRef Section;
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000746 if (getParser().parseIdentifier(Section))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000747 return TokError("expected section name after comma in '.zerofill' "
748 "directive");
749
750 // If this is the end of the line all that was wanted was to create the
751 // the section but with no symbol.
752 if (getLexer().is(AsmToken::EndOfStatement)) {
753 // Create the zerofill section but no symbol
754 getStreamer().EmitZerofill(getContext().getMachOSection(
755 Segment, Section, MCSectionMachO::S_ZEROFILL,
756 0, SectionKind::getBSS()));
757 return false;
758 }
759
760 if (getLexer().isNot(AsmToken::Comma))
761 return TokError("unexpected token in directive");
762 Lex();
763
764 SMLoc IDLoc = getLexer().getLoc();
765 StringRef IDStr;
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000766 if (getParser().parseIdentifier(IDStr))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000767 return TokError("expected identifier in directive");
768
769 // handle the identifier as the key symbol.
770 MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
771
772 if (getLexer().isNot(AsmToken::Comma))
773 return TokError("unexpected token in directive");
774 Lex();
775
776 int64_t Size;
777 SMLoc SizeLoc = getLexer().getLoc();
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000778 if (getParser().parseAbsoluteExpression(Size))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000779 return true;
780
781 int64_t Pow2Alignment = 0;
782 SMLoc Pow2AlignmentLoc;
783 if (getLexer().is(AsmToken::Comma)) {
784 Lex();
785 Pow2AlignmentLoc = getLexer().getLoc();
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000786 if (getParser().parseAbsoluteExpression(Pow2Alignment))
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000787 return true;
788 }
789
790 if (getLexer().isNot(AsmToken::EndOfStatement))
791 return TokError("unexpected token in '.zerofill' directive");
792
793 Lex();
794
795 if (Size < 0)
796 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
797 "than zero");
798
799 // NOTE: The alignment in the directive is a power of 2 value, the assembler
800 // may internally end up wanting an alignment in bytes.
801 // FIXME: Diagnose overflow.
802 if (Pow2Alignment < 0)
803 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
804 "can't be less than zero");
805
806 if (!Sym->isUndefined())
807 return Error(IDLoc, "invalid symbol redefinition");
808
809 // Create the zerofill Symbol with Size and Pow2Alignment
810 //
811 // FIXME: Arch specific.
812 getStreamer().EmitZerofill(getContext().getMachOSection(
813 Segment, Section, MCSectionMachO::S_ZEROFILL,
814 0, SectionKind::getBSS()),
815 Sym, Size, 1 << Pow2Alignment);
816
817 return false;
818}
819
Jim Grosbach3e965312012-05-18 19:12:01 +0000820/// ParseDirectiveDataRegion
821/// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
822bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
823 if (getLexer().is(AsmToken::EndOfStatement)) {
824 Lex();
825 getStreamer().EmitDataRegion(MCDR_DataRegion);
826 return false;
827 }
828 StringRef RegionType;
829 SMLoc Loc = getParser().getTok().getLoc();
Jim Grosbachcb2ae3d2013-02-20 22:21:35 +0000830 if (getParser().parseIdentifier(RegionType))
Jim Grosbach3e965312012-05-18 19:12:01 +0000831 return TokError("expected region type after '.data_region' directive");
832 int Kind = StringSwitch<int>(RegionType)
833 .Case("jt8", MCDR_DataRegionJT8)
834 .Case("jt16", MCDR_DataRegionJT16)
835 .Case("jt32", MCDR_DataRegionJT32)
836 .Default(-1);
837 if (Kind == -1)
838 return Error(Loc, "unknown region type in '.data_region' directive");
839 Lex();
840
841 getStreamer().EmitDataRegion((MCDataRegionType)Kind);
842 return false;
843}
844
845/// ParseDirectiveDataRegionEnd
846/// ::= .end_data_region
847bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef, SMLoc) {
848 if (getLexer().isNot(AsmToken::EndOfStatement))
849 return TokError("unexpected token in '.end_data_region' directive");
850
851 Lex();
852 getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
853 return false;
854}
855
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000856namespace llvm {
857
858MCAsmParserExtension *createDarwinAsmParser() {
859 return new DarwinAsmParser;
860}
861
Bill Wendlingef920552012-08-08 06:30:30 +0000862} // end llvm namespace