1f4a2713aSLionel Sambuc //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc
10f4a2713aSLionel Sambuc #include "llvm/MC/MCParser/MCAsmParserExtension.h"
11f4a2713aSLionel Sambuc #include "llvm/ADT/StringRef.h"
12f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h"
13f4a2713aSLionel Sambuc #include "llvm/ADT/Twine.h"
14f4a2713aSLionel Sambuc #include "llvm/MC/MCContext.h"
15f4a2713aSLionel Sambuc #include "llvm/MC/MCParser/MCAsmLexer.h"
16f4a2713aSLionel Sambuc #include "llvm/MC/MCParser/MCAsmParser.h"
17f4a2713aSLionel Sambuc #include "llvm/MC/MCSectionMachO.h"
18f4a2713aSLionel Sambuc #include "llvm/MC/MCStreamer.h"
19f4a2713aSLionel Sambuc #include "llvm/MC/MCSymbol.h"
20*0a6a1f1dSLionel Sambuc #include "llvm/Support/FileSystem.h"
21f4a2713aSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
22f4a2713aSLionel Sambuc #include "llvm/Support/SourceMgr.h"
23f4a2713aSLionel Sambuc using namespace llvm;
24f4a2713aSLionel Sambuc
25f4a2713aSLionel Sambuc namespace {
26f4a2713aSLionel Sambuc
27f4a2713aSLionel Sambuc /// \brief Implementation of directive handling which is shared across all
28f4a2713aSLionel Sambuc /// Darwin targets.
29f4a2713aSLionel Sambuc class DarwinAsmParser : public MCAsmParserExtension {
30f4a2713aSLionel Sambuc template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
addDirectiveHandler(StringRef Directive)31f4a2713aSLionel Sambuc void addDirectiveHandler(StringRef Directive) {
32f4a2713aSLionel Sambuc MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
33f4a2713aSLionel Sambuc this, HandleDirective<DarwinAsmParser, HandlerMethod>);
34f4a2713aSLionel Sambuc getParser().addDirectiveHandler(Directive, Handler);
35f4a2713aSLionel Sambuc }
36f4a2713aSLionel Sambuc
37*0a6a1f1dSLionel Sambuc bool parseSectionSwitch(const char *Segment, const char *Section,
38f4a2713aSLionel Sambuc unsigned TAA = 0, unsigned ImplicitAlign = 0,
39f4a2713aSLionel Sambuc unsigned StubSize = 0);
40f4a2713aSLionel Sambuc
41f4a2713aSLionel Sambuc public:
DarwinAsmParser()42f4a2713aSLionel Sambuc DarwinAsmParser() {}
43f4a2713aSLionel Sambuc
Initialize(MCAsmParser & Parser)44*0a6a1f1dSLionel Sambuc void Initialize(MCAsmParser &Parser) override {
45f4a2713aSLionel Sambuc // Call the base implementation.
46f4a2713aSLionel Sambuc this->MCAsmParserExtension::Initialize(Parser);
47f4a2713aSLionel Sambuc
48*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");
49*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(
50f4a2713aSLionel Sambuc ".indirect_symbol");
51*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym");
52*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>(
53f4a2713aSLionel Sambuc ".subsections_via_symbols");
54*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump");
55*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load");
56*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section");
57*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>(
58f4a2713aSLionel Sambuc ".pushsection");
59*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>(
60f4a2713aSLionel Sambuc ".popsection");
61*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous");
62*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>(
63f4a2713aSLionel Sambuc ".secure_log_unique");
64*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>(
65f4a2713aSLionel Sambuc ".secure_log_reset");
66*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss");
67*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill");
68f4a2713aSLionel Sambuc
69*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>(
70f4a2713aSLionel Sambuc ".data_region");
71*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>(
72f4a2713aSLionel Sambuc ".end_data_region");
73f4a2713aSLionel Sambuc
74f4a2713aSLionel Sambuc // Special section directives.
75*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss");
76*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const");
77*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>(
78f4a2713aSLionel Sambuc ".const_data");
79*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>(
80f4a2713aSLionel Sambuc ".constructor");
81*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>(
82f4a2713aSLionel Sambuc ".cstring");
83*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data");
84*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>(
85f4a2713aSLionel Sambuc ".destructor");
86*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld");
87*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>(
88f4a2713aSLionel Sambuc ".fvmlib_init0");
89*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>(
90f4a2713aSLionel Sambuc ".fvmlib_init1");
91f4a2713aSLionel Sambuc addDirectiveHandler<
92*0a6a1f1dSLionel Sambuc &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>(
93f4a2713aSLionel Sambuc ".lazy_symbol_pointer");
94*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>(
95f4a2713aSLionel Sambuc ".linker_option");
96*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>(
97f4a2713aSLionel Sambuc ".literal16");
98*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>(
99f4a2713aSLionel Sambuc ".literal4");
100*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>(
101f4a2713aSLionel Sambuc ".literal8");
102*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>(
103f4a2713aSLionel Sambuc ".mod_init_func");
104*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>(
105f4a2713aSLionel Sambuc ".mod_term_func");
106f4a2713aSLionel Sambuc addDirectiveHandler<
107*0a6a1f1dSLionel Sambuc &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(
108f4a2713aSLionel Sambuc ".non_lazy_symbol_pointer");
109*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(
110f4a2713aSLionel Sambuc ".objc_cat_cls_meth");
111*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(
112f4a2713aSLionel Sambuc ".objc_cat_inst_meth");
113*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>(
114f4a2713aSLionel Sambuc ".objc_category");
115*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>(
116f4a2713aSLionel Sambuc ".objc_class");
117*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>(
118f4a2713aSLionel Sambuc ".objc_class_names");
119*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>(
120f4a2713aSLionel Sambuc ".objc_class_vars");
121*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>(
122f4a2713aSLionel Sambuc ".objc_cls_meth");
123*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>(
124f4a2713aSLionel Sambuc ".objc_cls_refs");
125*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>(
126f4a2713aSLionel Sambuc ".objc_inst_meth");
127f4a2713aSLionel Sambuc addDirectiveHandler<
128*0a6a1f1dSLionel Sambuc &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>(
129f4a2713aSLionel Sambuc ".objc_instance_vars");
130*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>(
131f4a2713aSLionel Sambuc ".objc_message_refs");
132*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>(
133f4a2713aSLionel Sambuc ".objc_meta_class");
134f4a2713aSLionel Sambuc addDirectiveHandler<
135*0a6a1f1dSLionel Sambuc &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>(
136f4a2713aSLionel Sambuc ".objc_meth_var_names");
137f4a2713aSLionel Sambuc addDirectiveHandler<
138*0a6a1f1dSLionel Sambuc &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>(
139f4a2713aSLionel Sambuc ".objc_meth_var_types");
140*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>(
141f4a2713aSLionel Sambuc ".objc_module_info");
142*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>(
143f4a2713aSLionel Sambuc ".objc_protocol");
144f4a2713aSLionel Sambuc addDirectiveHandler<
145*0a6a1f1dSLionel Sambuc &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>(
146f4a2713aSLionel Sambuc ".objc_selector_strs");
147f4a2713aSLionel Sambuc addDirectiveHandler<
148*0a6a1f1dSLionel Sambuc &DarwinAsmParser::parseSectionDirectiveObjCStringObject>(
149f4a2713aSLionel Sambuc ".objc_string_object");
150*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>(
151f4a2713aSLionel Sambuc ".objc_symbols");
152*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>(
153f4a2713aSLionel Sambuc ".picsymbol_stub");
154*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>(
155f4a2713aSLionel Sambuc ".static_const");
156*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>(
157f4a2713aSLionel Sambuc ".static_data");
158*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>(
159f4a2713aSLionel Sambuc ".symbol_stub");
160*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata");
161*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text");
162*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>(
163f4a2713aSLionel Sambuc ".thread_init_func");
164*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
165f4a2713aSLionel Sambuc
166*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
167*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min");
168*0a6a1f1dSLionel Sambuc addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
169*0a6a1f1dSLionel Sambuc ".macosx_version_min");
170f4a2713aSLionel Sambuc }
171f4a2713aSLionel Sambuc
172*0a6a1f1dSLionel Sambuc bool parseDirectiveDesc(StringRef, SMLoc);
173*0a6a1f1dSLionel Sambuc bool parseDirectiveIndirectSymbol(StringRef, SMLoc);
174*0a6a1f1dSLionel Sambuc bool parseDirectiveDumpOrLoad(StringRef, SMLoc);
175*0a6a1f1dSLionel Sambuc bool parseDirectiveLsym(StringRef, SMLoc);
176*0a6a1f1dSLionel Sambuc bool parseDirectiveLinkerOption(StringRef, SMLoc);
177*0a6a1f1dSLionel Sambuc bool parseDirectiveSection(StringRef, SMLoc);
178*0a6a1f1dSLionel Sambuc bool parseDirectivePushSection(StringRef, SMLoc);
179*0a6a1f1dSLionel Sambuc bool parseDirectivePopSection(StringRef, SMLoc);
180*0a6a1f1dSLionel Sambuc bool parseDirectivePrevious(StringRef, SMLoc);
181*0a6a1f1dSLionel Sambuc bool parseDirectiveSecureLogReset(StringRef, SMLoc);
182*0a6a1f1dSLionel Sambuc bool parseDirectiveSecureLogUnique(StringRef, SMLoc);
183*0a6a1f1dSLionel Sambuc bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
184*0a6a1f1dSLionel Sambuc bool parseDirectiveTBSS(StringRef, SMLoc);
185*0a6a1f1dSLionel Sambuc bool parseDirectiveZerofill(StringRef, SMLoc);
186*0a6a1f1dSLionel Sambuc bool parseDirectiveDataRegion(StringRef, SMLoc);
187*0a6a1f1dSLionel Sambuc bool parseDirectiveDataRegionEnd(StringRef, SMLoc);
188f4a2713aSLionel Sambuc
189f4a2713aSLionel Sambuc // Named Section Directive
parseSectionDirectiveBss(StringRef,SMLoc)190*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveBss(StringRef, SMLoc) {
191*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__bss");
192f4a2713aSLionel Sambuc }
193f4a2713aSLionel Sambuc
parseSectionDirectiveConst(StringRef,SMLoc)194*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveConst(StringRef, SMLoc) {
195*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT", "__const");
196f4a2713aSLionel Sambuc }
parseSectionDirectiveStaticConst(StringRef,SMLoc)197*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveStaticConst(StringRef, SMLoc) {
198*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT", "__static_const");
199f4a2713aSLionel Sambuc }
parseSectionDirectiveCString(StringRef,SMLoc)200*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveCString(StringRef, SMLoc) {
201*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT","__cstring",
202*0a6a1f1dSLionel Sambuc MachO::S_CSTRING_LITERALS);
203f4a2713aSLionel Sambuc }
parseSectionDirectiveLiteral4(StringRef,SMLoc)204*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveLiteral4(StringRef, SMLoc) {
205*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT", "__literal4",
206*0a6a1f1dSLionel Sambuc MachO::S_4BYTE_LITERALS, 4);
207f4a2713aSLionel Sambuc }
parseSectionDirectiveLiteral8(StringRef,SMLoc)208*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveLiteral8(StringRef, SMLoc) {
209*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT", "__literal8",
210*0a6a1f1dSLionel Sambuc MachO::S_8BYTE_LITERALS, 8);
211f4a2713aSLionel Sambuc }
parseSectionDirectiveLiteral16(StringRef,SMLoc)212*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveLiteral16(StringRef, SMLoc) {
213*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT","__literal16",
214*0a6a1f1dSLionel Sambuc MachO::S_16BYTE_LITERALS, 16);
215f4a2713aSLionel Sambuc }
parseSectionDirectiveConstructor(StringRef,SMLoc)216*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveConstructor(StringRef, SMLoc) {
217*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT","__constructor");
218f4a2713aSLionel Sambuc }
parseSectionDirectiveDestructor(StringRef,SMLoc)219*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveDestructor(StringRef, SMLoc) {
220*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT","__destructor");
221f4a2713aSLionel Sambuc }
parseSectionDirectiveFVMLibInit0(StringRef,SMLoc)222*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
223*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT","__fvmlib_init0");
224f4a2713aSLionel Sambuc }
parseSectionDirectiveFVMLibInit1(StringRef,SMLoc)225*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
226*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT","__fvmlib_init1");
227f4a2713aSLionel Sambuc }
parseSectionDirectiveSymbolStub(StringRef,SMLoc)228*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {
229*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT","__symbol_stub",
230*0a6a1f1dSLionel Sambuc MachO::S_SYMBOL_STUBS |
231*0a6a1f1dSLionel Sambuc MachO::S_ATTR_PURE_INSTRUCTIONS,
232f4a2713aSLionel Sambuc // FIXME: Different on PPC and ARM.
233f4a2713aSLionel Sambuc 0, 16);
234f4a2713aSLionel Sambuc }
parseSectionDirectivePICSymbolStub(StringRef,SMLoc)235*0a6a1f1dSLionel Sambuc bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
236*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT","__picsymbol_stub",
237*0a6a1f1dSLionel Sambuc MachO::S_SYMBOL_STUBS |
238*0a6a1f1dSLionel Sambuc MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
239f4a2713aSLionel Sambuc }
parseSectionDirectiveData(StringRef,SMLoc)240*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveData(StringRef, SMLoc) {
241*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__data");
242f4a2713aSLionel Sambuc }
parseSectionDirectiveStaticData(StringRef,SMLoc)243*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveStaticData(StringRef, SMLoc) {
244*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__static_data");
245f4a2713aSLionel Sambuc }
parseSectionDirectiveNonLazySymbolPointers(StringRef,SMLoc)246*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
247*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__nl_symbol_ptr",
248*0a6a1f1dSLionel Sambuc MachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
249f4a2713aSLionel Sambuc }
parseSectionDirectiveLazySymbolPointers(StringRef,SMLoc)250*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
251*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__la_symbol_ptr",
252*0a6a1f1dSLionel Sambuc MachO::S_LAZY_SYMBOL_POINTERS, 4);
253f4a2713aSLionel Sambuc }
parseSectionDirectiveDyld(StringRef,SMLoc)254*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveDyld(StringRef, SMLoc) {
255*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__dyld");
256f4a2713aSLionel Sambuc }
parseSectionDirectiveModInitFunc(StringRef,SMLoc)257*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) {
258*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__mod_init_func",
259*0a6a1f1dSLionel Sambuc MachO::S_MOD_INIT_FUNC_POINTERS, 4);
260f4a2713aSLionel Sambuc }
parseSectionDirectiveModTermFunc(StringRef,SMLoc)261*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) {
262*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__mod_term_func",
263*0a6a1f1dSLionel Sambuc MachO::S_MOD_TERM_FUNC_POINTERS, 4);
264f4a2713aSLionel Sambuc }
parseSectionDirectiveConstData(StringRef,SMLoc)265*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveConstData(StringRef, SMLoc) {
266*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__const");
267f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCClass(StringRef,SMLoc)268*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCClass(StringRef, SMLoc) {
269*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__class",
270*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
271f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCMetaClass(StringRef,SMLoc)272*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
273*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__meta_class",
274*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
275f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCCatClsMeth(StringRef,SMLoc)276*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
277*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__cat_cls_meth",
278*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
279f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCCatInstMeth(StringRef,SMLoc)280*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
281*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__cat_inst_meth",
282*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
283f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCProtocol(StringRef,SMLoc)284*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
285*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__protocol",
286*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
287f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCStringObject(StringRef,SMLoc)288*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
289*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__string_object",
290*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
291f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCClsMeth(StringRef,SMLoc)292*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
293*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__cls_meth",
294*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
295f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCInstMeth(StringRef,SMLoc)296*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
297*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__inst_meth",
298*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
299f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCClsRefs(StringRef,SMLoc)300*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
301*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__cls_refs",
302*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP |
303*0a6a1f1dSLionel Sambuc MachO::S_LITERAL_POINTERS, 4);
304f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCMessageRefs(StringRef,SMLoc)305*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
306*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__message_refs",
307*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP |
308*0a6a1f1dSLionel Sambuc MachO::S_LITERAL_POINTERS, 4);
309f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCSymbols(StringRef,SMLoc)310*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
311*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__symbols",
312*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
313f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCCategory(StringRef,SMLoc)314*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) {
315*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__category",
316*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
317f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCClassVars(StringRef,SMLoc)318*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
319*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__class_vars",
320*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
321f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCInstanceVars(StringRef,SMLoc)322*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
323*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__instance_vars",
324*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
325f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCModuleInfo(StringRef,SMLoc)326*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
327*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__module_info",
328*0a6a1f1dSLionel Sambuc MachO::S_ATTR_NO_DEAD_STRIP);
329f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCClassNames(StringRef,SMLoc)330*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
331*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT", "__cstring",
332*0a6a1f1dSLionel Sambuc MachO::S_CSTRING_LITERALS);
333f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCMethVarTypes(StringRef,SMLoc)334*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
335*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT", "__cstring",
336*0a6a1f1dSLionel Sambuc MachO::S_CSTRING_LITERALS);
337f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCMethVarNames(StringRef,SMLoc)338*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
339*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT", "__cstring",
340*0a6a1f1dSLionel Sambuc MachO::S_CSTRING_LITERALS);
341f4a2713aSLionel Sambuc }
parseSectionDirectiveObjCSelectorStrs(StringRef,SMLoc)342*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
343*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__OBJC", "__selector_strs",
344*0a6a1f1dSLionel Sambuc MachO::S_CSTRING_LITERALS);
345f4a2713aSLionel Sambuc }
parseSectionDirectiveTData(StringRef,SMLoc)346*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveTData(StringRef, SMLoc) {
347*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__thread_data",
348*0a6a1f1dSLionel Sambuc MachO::S_THREAD_LOCAL_REGULAR);
349f4a2713aSLionel Sambuc }
parseSectionDirectiveText(StringRef,SMLoc)350*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveText(StringRef, SMLoc) {
351*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__TEXT", "__text",
352*0a6a1f1dSLionel Sambuc MachO::S_ATTR_PURE_INSTRUCTIONS);
353f4a2713aSLionel Sambuc }
parseSectionDirectiveTLV(StringRef,SMLoc)354*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveTLV(StringRef, SMLoc) {
355*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__thread_vars",
356*0a6a1f1dSLionel Sambuc MachO::S_THREAD_LOCAL_VARIABLES);
357f4a2713aSLionel Sambuc }
parseSectionDirectiveIdent(StringRef,SMLoc)358*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveIdent(StringRef, SMLoc) {
359f4a2713aSLionel Sambuc // Darwin silently ignores the .ident directive.
360f4a2713aSLionel Sambuc getParser().eatToEndOfStatement();
361f4a2713aSLionel Sambuc return false;
362f4a2713aSLionel Sambuc }
parseSectionDirectiveThreadInitFunc(StringRef,SMLoc)363*0a6a1f1dSLionel Sambuc bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
364*0a6a1f1dSLionel Sambuc return parseSectionSwitch("__DATA", "__thread_init",
365*0a6a1f1dSLionel Sambuc MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
366f4a2713aSLionel Sambuc }
367*0a6a1f1dSLionel Sambuc bool parseVersionMin(StringRef, SMLoc);
368f4a2713aSLionel Sambuc
369f4a2713aSLionel Sambuc };
370f4a2713aSLionel Sambuc
371f4a2713aSLionel Sambuc } // end anonymous namespace
372f4a2713aSLionel Sambuc
parseSectionSwitch(const char * Segment,const char * Section,unsigned TAA,unsigned Align,unsigned StubSize)373*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseSectionSwitch(const char *Segment,
374f4a2713aSLionel Sambuc const char *Section,
375f4a2713aSLionel Sambuc unsigned TAA, unsigned Align,
376f4a2713aSLionel Sambuc unsigned StubSize) {
377f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
378f4a2713aSLionel Sambuc return TokError("unexpected token in section switching directive");
379f4a2713aSLionel Sambuc Lex();
380f4a2713aSLionel Sambuc
381f4a2713aSLionel Sambuc // FIXME: Arch specific.
382*0a6a1f1dSLionel Sambuc bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS;
383f4a2713aSLionel Sambuc getStreamer().SwitchSection(getContext().getMachOSection(
384f4a2713aSLionel Sambuc Segment, Section, TAA, StubSize,
385f4a2713aSLionel Sambuc isText ? SectionKind::getText()
386f4a2713aSLionel Sambuc : SectionKind::getDataRel()));
387f4a2713aSLionel Sambuc
388f4a2713aSLionel Sambuc // Set the implicit alignment, if any.
389f4a2713aSLionel Sambuc //
390f4a2713aSLionel Sambuc // FIXME: This isn't really what 'as' does; I think it just uses the implicit
391f4a2713aSLionel Sambuc // alignment on the section (e.g., if one manually inserts bytes into the
392f4a2713aSLionel Sambuc // section, then just issuing the section switch directive will not realign
393f4a2713aSLionel Sambuc // the section. However, this is arguably more reasonable behavior, and there
394f4a2713aSLionel Sambuc // is no good reason for someone to intentionally emit incorrectly sized
395f4a2713aSLionel Sambuc // values into the implicitly aligned sections.
396f4a2713aSLionel Sambuc if (Align)
397*0a6a1f1dSLionel Sambuc getStreamer().EmitValueToAlignment(Align);
398f4a2713aSLionel Sambuc
399f4a2713aSLionel Sambuc return false;
400f4a2713aSLionel Sambuc }
401f4a2713aSLionel Sambuc
402*0a6a1f1dSLionel Sambuc /// parseDirectiveDesc
403f4a2713aSLionel Sambuc /// ::= .desc identifier , expression
parseDirectiveDesc(StringRef,SMLoc)404*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {
405f4a2713aSLionel Sambuc StringRef Name;
406f4a2713aSLionel Sambuc if (getParser().parseIdentifier(Name))
407f4a2713aSLionel Sambuc return TokError("expected identifier in directive");
408f4a2713aSLionel Sambuc
409f4a2713aSLionel Sambuc // Handle the identifier as the key symbol.
410f4a2713aSLionel Sambuc MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
411f4a2713aSLionel Sambuc
412f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::Comma))
413f4a2713aSLionel Sambuc return TokError("unexpected token in '.desc' directive");
414f4a2713aSLionel Sambuc Lex();
415f4a2713aSLionel Sambuc
416f4a2713aSLionel Sambuc int64_t DescValue;
417f4a2713aSLionel Sambuc if (getParser().parseAbsoluteExpression(DescValue))
418f4a2713aSLionel Sambuc return true;
419f4a2713aSLionel Sambuc
420f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
421f4a2713aSLionel Sambuc return TokError("unexpected token in '.desc' directive");
422f4a2713aSLionel Sambuc
423f4a2713aSLionel Sambuc Lex();
424f4a2713aSLionel Sambuc
425f4a2713aSLionel Sambuc // Set the n_desc field of this Symbol to this DescValue
426f4a2713aSLionel Sambuc getStreamer().EmitSymbolDesc(Sym, DescValue);
427f4a2713aSLionel Sambuc
428f4a2713aSLionel Sambuc return false;
429f4a2713aSLionel Sambuc }
430f4a2713aSLionel Sambuc
431*0a6a1f1dSLionel Sambuc /// parseDirectiveIndirectSymbol
432f4a2713aSLionel Sambuc /// ::= .indirect_symbol identifier
parseDirectiveIndirectSymbol(StringRef,SMLoc Loc)433*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
434f4a2713aSLionel Sambuc const MCSectionMachO *Current = static_cast<const MCSectionMachO*>(
435f4a2713aSLionel Sambuc getStreamer().getCurrentSection().first);
436*0a6a1f1dSLionel Sambuc MachO::SectionType SectionType = Current->getType();
437*0a6a1f1dSLionel Sambuc if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
438*0a6a1f1dSLionel Sambuc SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&
439*0a6a1f1dSLionel Sambuc SectionType != MachO::S_SYMBOL_STUBS)
440f4a2713aSLionel Sambuc return Error(Loc, "indirect symbol not in a symbol pointer or stub "
441f4a2713aSLionel Sambuc "section");
442f4a2713aSLionel Sambuc
443f4a2713aSLionel Sambuc StringRef Name;
444f4a2713aSLionel Sambuc if (getParser().parseIdentifier(Name))
445f4a2713aSLionel Sambuc return TokError("expected identifier in .indirect_symbol directive");
446f4a2713aSLionel Sambuc
447f4a2713aSLionel Sambuc MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
448f4a2713aSLionel Sambuc
449f4a2713aSLionel Sambuc // Assembler local symbols don't make any sense here. Complain loudly.
450f4a2713aSLionel Sambuc if (Sym->isTemporary())
451f4a2713aSLionel Sambuc return TokError("non-local symbol required in directive");
452f4a2713aSLionel Sambuc
453f4a2713aSLionel Sambuc if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol))
454f4a2713aSLionel Sambuc return TokError("unable to emit indirect symbol attribute for: " + Name);
455f4a2713aSLionel Sambuc
456f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
457f4a2713aSLionel Sambuc return TokError("unexpected token in '.indirect_symbol' directive");
458f4a2713aSLionel Sambuc
459f4a2713aSLionel Sambuc Lex();
460f4a2713aSLionel Sambuc
461f4a2713aSLionel Sambuc return false;
462f4a2713aSLionel Sambuc }
463f4a2713aSLionel Sambuc
464*0a6a1f1dSLionel Sambuc /// parseDirectiveDumpOrLoad
465f4a2713aSLionel Sambuc /// ::= ( .dump | .load ) "filename"
parseDirectiveDumpOrLoad(StringRef Directive,SMLoc IDLoc)466*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive,
467f4a2713aSLionel Sambuc SMLoc IDLoc) {
468f4a2713aSLionel Sambuc bool IsDump = Directive == ".dump";
469f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::String))
470f4a2713aSLionel Sambuc return TokError("expected string in '.dump' or '.load' directive");
471f4a2713aSLionel Sambuc
472f4a2713aSLionel Sambuc Lex();
473f4a2713aSLionel Sambuc
474f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
475f4a2713aSLionel Sambuc return TokError("unexpected token in '.dump' or '.load' directive");
476f4a2713aSLionel Sambuc
477f4a2713aSLionel Sambuc Lex();
478f4a2713aSLionel Sambuc
479f4a2713aSLionel Sambuc // FIXME: If/when .dump and .load are implemented they will be done in the
480f4a2713aSLionel Sambuc // the assembly parser and not have any need for an MCStreamer API.
481f4a2713aSLionel Sambuc if (IsDump)
482f4a2713aSLionel Sambuc return Warning(IDLoc, "ignoring directive .dump for now");
483f4a2713aSLionel Sambuc else
484f4a2713aSLionel Sambuc return Warning(IDLoc, "ignoring directive .load for now");
485f4a2713aSLionel Sambuc }
486f4a2713aSLionel Sambuc
487f4a2713aSLionel Sambuc /// ParseDirectiveLinkerOption
488f4a2713aSLionel Sambuc /// ::= .linker_option "string" ( , "string" )*
parseDirectiveLinkerOption(StringRef IDVal,SMLoc)489*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
490f4a2713aSLionel Sambuc SmallVector<std::string, 4> Args;
491f4a2713aSLionel Sambuc for (;;) {
492f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::String))
493f4a2713aSLionel Sambuc return TokError("expected string in '" + Twine(IDVal) + "' directive");
494f4a2713aSLionel Sambuc
495f4a2713aSLionel Sambuc std::string Data;
496f4a2713aSLionel Sambuc if (getParser().parseEscapedString(Data))
497f4a2713aSLionel Sambuc return true;
498f4a2713aSLionel Sambuc
499f4a2713aSLionel Sambuc Args.push_back(Data);
500f4a2713aSLionel Sambuc
501f4a2713aSLionel Sambuc Lex();
502f4a2713aSLionel Sambuc if (getLexer().is(AsmToken::EndOfStatement))
503f4a2713aSLionel Sambuc break;
504f4a2713aSLionel Sambuc
505f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::Comma))
506f4a2713aSLionel Sambuc return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
507f4a2713aSLionel Sambuc Lex();
508f4a2713aSLionel Sambuc }
509f4a2713aSLionel Sambuc
510f4a2713aSLionel Sambuc getStreamer().EmitLinkerOptions(Args);
511f4a2713aSLionel Sambuc return false;
512f4a2713aSLionel Sambuc }
513f4a2713aSLionel Sambuc
514*0a6a1f1dSLionel Sambuc /// parseDirectiveLsym
515f4a2713aSLionel Sambuc /// ::= .lsym identifier , expression
parseDirectiveLsym(StringRef,SMLoc)516*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) {
517f4a2713aSLionel Sambuc StringRef Name;
518f4a2713aSLionel Sambuc if (getParser().parseIdentifier(Name))
519f4a2713aSLionel Sambuc return TokError("expected identifier in directive");
520f4a2713aSLionel Sambuc
521f4a2713aSLionel Sambuc // Handle the identifier as the key symbol.
522f4a2713aSLionel Sambuc MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
523f4a2713aSLionel Sambuc
524f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::Comma))
525f4a2713aSLionel Sambuc return TokError("unexpected token in '.lsym' directive");
526f4a2713aSLionel Sambuc Lex();
527f4a2713aSLionel Sambuc
528f4a2713aSLionel Sambuc const MCExpr *Value;
529f4a2713aSLionel Sambuc if (getParser().parseExpression(Value))
530f4a2713aSLionel Sambuc return true;
531f4a2713aSLionel Sambuc
532f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
533f4a2713aSLionel Sambuc return TokError("unexpected token in '.lsym' directive");
534f4a2713aSLionel Sambuc
535f4a2713aSLionel Sambuc Lex();
536f4a2713aSLionel Sambuc
537f4a2713aSLionel Sambuc // We don't currently support this directive.
538f4a2713aSLionel Sambuc //
539f4a2713aSLionel Sambuc // FIXME: Diagnostic location!
540f4a2713aSLionel Sambuc (void) Sym;
541f4a2713aSLionel Sambuc return TokError("directive '.lsym' is unsupported");
542f4a2713aSLionel Sambuc }
543f4a2713aSLionel Sambuc
544*0a6a1f1dSLionel Sambuc /// parseDirectiveSection:
545f4a2713aSLionel Sambuc /// ::= .section identifier (',' identifier)*
parseDirectiveSection(StringRef,SMLoc)546*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {
547f4a2713aSLionel Sambuc SMLoc Loc = getLexer().getLoc();
548f4a2713aSLionel Sambuc
549f4a2713aSLionel Sambuc StringRef SectionName;
550f4a2713aSLionel Sambuc if (getParser().parseIdentifier(SectionName))
551f4a2713aSLionel Sambuc return Error(Loc, "expected identifier after '.section' directive");
552f4a2713aSLionel Sambuc
553f4a2713aSLionel Sambuc // Verify there is a following comma.
554f4a2713aSLionel Sambuc if (!getLexer().is(AsmToken::Comma))
555f4a2713aSLionel Sambuc return TokError("unexpected token in '.section' directive");
556f4a2713aSLionel Sambuc
557f4a2713aSLionel Sambuc std::string SectionSpec = SectionName;
558f4a2713aSLionel Sambuc SectionSpec += ",";
559f4a2713aSLionel Sambuc
560f4a2713aSLionel Sambuc // Add all the tokens until the end of the line, ParseSectionSpecifier will
561f4a2713aSLionel Sambuc // handle this.
562f4a2713aSLionel Sambuc StringRef EOL = getLexer().LexUntilEndOfStatement();
563f4a2713aSLionel Sambuc SectionSpec.append(EOL.begin(), EOL.end());
564f4a2713aSLionel Sambuc
565f4a2713aSLionel Sambuc Lex();
566f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
567f4a2713aSLionel Sambuc return TokError("unexpected token in '.section' directive");
568f4a2713aSLionel Sambuc Lex();
569f4a2713aSLionel Sambuc
570f4a2713aSLionel Sambuc
571f4a2713aSLionel Sambuc StringRef Segment, Section;
572f4a2713aSLionel Sambuc unsigned StubSize;
573f4a2713aSLionel Sambuc unsigned TAA;
574f4a2713aSLionel Sambuc bool TAAParsed;
575f4a2713aSLionel Sambuc std::string ErrorStr =
576f4a2713aSLionel Sambuc MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
577f4a2713aSLionel Sambuc TAA, TAAParsed, StubSize);
578f4a2713aSLionel Sambuc
579f4a2713aSLionel Sambuc if (!ErrorStr.empty())
580f4a2713aSLionel Sambuc return Error(Loc, ErrorStr.c_str());
581f4a2713aSLionel Sambuc
582f4a2713aSLionel Sambuc // FIXME: Arch specific.
583f4a2713aSLionel Sambuc bool isText = Segment == "__TEXT"; // FIXME: Hack.
584f4a2713aSLionel Sambuc getStreamer().SwitchSection(getContext().getMachOSection(
585f4a2713aSLionel Sambuc Segment, Section, TAA, StubSize,
586f4a2713aSLionel Sambuc isText ? SectionKind::getText()
587f4a2713aSLionel Sambuc : SectionKind::getDataRel()));
588f4a2713aSLionel Sambuc return false;
589f4a2713aSLionel Sambuc }
590f4a2713aSLionel Sambuc
591f4a2713aSLionel Sambuc /// ParseDirectivePushSection:
592f4a2713aSLionel Sambuc /// ::= .pushsection identifier (',' identifier)*
parseDirectivePushSection(StringRef S,SMLoc Loc)593*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) {
594f4a2713aSLionel Sambuc getStreamer().PushSection();
595f4a2713aSLionel Sambuc
596*0a6a1f1dSLionel Sambuc if (parseDirectiveSection(S, Loc)) {
597f4a2713aSLionel Sambuc getStreamer().PopSection();
598f4a2713aSLionel Sambuc return true;
599f4a2713aSLionel Sambuc }
600f4a2713aSLionel Sambuc
601f4a2713aSLionel Sambuc return false;
602f4a2713aSLionel Sambuc }
603f4a2713aSLionel Sambuc
604f4a2713aSLionel Sambuc /// ParseDirectivePopSection:
605f4a2713aSLionel Sambuc /// ::= .popsection
parseDirectivePopSection(StringRef,SMLoc)606*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
607f4a2713aSLionel Sambuc if (!getStreamer().PopSection())
608f4a2713aSLionel Sambuc return TokError(".popsection without corresponding .pushsection");
609f4a2713aSLionel Sambuc return false;
610f4a2713aSLionel Sambuc }
611f4a2713aSLionel Sambuc
612f4a2713aSLionel Sambuc /// ParseDirectivePrevious:
613f4a2713aSLionel Sambuc /// ::= .previous
parseDirectivePrevious(StringRef DirName,SMLoc)614*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {
615f4a2713aSLionel Sambuc MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
616*0a6a1f1dSLionel Sambuc if (!PreviousSection.first)
617f4a2713aSLionel Sambuc return TokError(".previous without corresponding .section");
618f4a2713aSLionel Sambuc getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
619f4a2713aSLionel Sambuc return false;
620f4a2713aSLionel Sambuc }
621f4a2713aSLionel Sambuc
622f4a2713aSLionel Sambuc /// ParseDirectiveSecureLogUnique
623f4a2713aSLionel Sambuc /// ::= .secure_log_unique ... message ...
parseDirectiveSecureLogUnique(StringRef,SMLoc IDLoc)624*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
625f4a2713aSLionel Sambuc StringRef LogMessage = getParser().parseStringToEndOfStatement();
626f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
627f4a2713aSLionel Sambuc return TokError("unexpected token in '.secure_log_unique' directive");
628f4a2713aSLionel Sambuc
629f4a2713aSLionel Sambuc if (getContext().getSecureLogUsed() != false)
630f4a2713aSLionel Sambuc return Error(IDLoc, ".secure_log_unique specified multiple times");
631f4a2713aSLionel Sambuc
632f4a2713aSLionel Sambuc // Get the secure log path.
633f4a2713aSLionel Sambuc const char *SecureLogFile = getContext().getSecureLogFile();
634*0a6a1f1dSLionel Sambuc if (!SecureLogFile)
635f4a2713aSLionel Sambuc return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
636f4a2713aSLionel Sambuc "environment variable unset.");
637f4a2713aSLionel Sambuc
638f4a2713aSLionel Sambuc // Open the secure log file if we haven't already.
639f4a2713aSLionel Sambuc raw_ostream *OS = getContext().getSecureLog();
640*0a6a1f1dSLionel Sambuc if (!OS) {
641*0a6a1f1dSLionel Sambuc std::error_code EC;
642*0a6a1f1dSLionel Sambuc OS = new raw_fd_ostream(SecureLogFile, EC,
643*0a6a1f1dSLionel Sambuc sys::fs::F_Append | sys::fs::F_Text);
644*0a6a1f1dSLionel Sambuc if (EC) {
645f4a2713aSLionel Sambuc delete OS;
646f4a2713aSLionel Sambuc return Error(IDLoc, Twine("can't open secure log file: ") +
647*0a6a1f1dSLionel Sambuc SecureLogFile + " (" + EC.message() + ")");
648f4a2713aSLionel Sambuc }
649f4a2713aSLionel Sambuc getContext().setSecureLog(OS);
650f4a2713aSLionel Sambuc }
651f4a2713aSLionel Sambuc
652f4a2713aSLionel Sambuc // Write the message.
653*0a6a1f1dSLionel Sambuc unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
654f4a2713aSLionel Sambuc *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
655f4a2713aSLionel Sambuc << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
656f4a2713aSLionel Sambuc << LogMessage + "\n";
657f4a2713aSLionel Sambuc
658f4a2713aSLionel Sambuc getContext().setSecureLogUsed(true);
659f4a2713aSLionel Sambuc
660f4a2713aSLionel Sambuc return false;
661f4a2713aSLionel Sambuc }
662f4a2713aSLionel Sambuc
663f4a2713aSLionel Sambuc /// ParseDirectiveSecureLogReset
664f4a2713aSLionel Sambuc /// ::= .secure_log_reset
parseDirectiveSecureLogReset(StringRef,SMLoc IDLoc)665*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
666f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
667f4a2713aSLionel Sambuc return TokError("unexpected token in '.secure_log_reset' directive");
668f4a2713aSLionel Sambuc
669f4a2713aSLionel Sambuc Lex();
670f4a2713aSLionel Sambuc
671f4a2713aSLionel Sambuc getContext().setSecureLogUsed(false);
672f4a2713aSLionel Sambuc
673f4a2713aSLionel Sambuc return false;
674f4a2713aSLionel Sambuc }
675f4a2713aSLionel Sambuc
676*0a6a1f1dSLionel Sambuc /// parseDirectiveSubsectionsViaSymbols
677f4a2713aSLionel Sambuc /// ::= .subsections_via_symbols
parseDirectiveSubsectionsViaSymbols(StringRef,SMLoc)678*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
679f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
680f4a2713aSLionel Sambuc return TokError("unexpected token in '.subsections_via_symbols' directive");
681f4a2713aSLionel Sambuc
682f4a2713aSLionel Sambuc Lex();
683f4a2713aSLionel Sambuc
684f4a2713aSLionel Sambuc getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
685f4a2713aSLionel Sambuc
686f4a2713aSLionel Sambuc return false;
687f4a2713aSLionel Sambuc }
688f4a2713aSLionel Sambuc
689f4a2713aSLionel Sambuc /// ParseDirectiveTBSS
690f4a2713aSLionel Sambuc /// ::= .tbss identifier, size, align
parseDirectiveTBSS(StringRef,SMLoc)691*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) {
692f4a2713aSLionel Sambuc SMLoc IDLoc = getLexer().getLoc();
693f4a2713aSLionel Sambuc StringRef Name;
694f4a2713aSLionel Sambuc if (getParser().parseIdentifier(Name))
695f4a2713aSLionel Sambuc return TokError("expected identifier in directive");
696f4a2713aSLionel Sambuc
697f4a2713aSLionel Sambuc // Handle the identifier as the key symbol.
698f4a2713aSLionel Sambuc MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
699f4a2713aSLionel Sambuc
700f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::Comma))
701f4a2713aSLionel Sambuc return TokError("unexpected token in directive");
702f4a2713aSLionel Sambuc Lex();
703f4a2713aSLionel Sambuc
704f4a2713aSLionel Sambuc int64_t Size;
705f4a2713aSLionel Sambuc SMLoc SizeLoc = getLexer().getLoc();
706f4a2713aSLionel Sambuc if (getParser().parseAbsoluteExpression(Size))
707f4a2713aSLionel Sambuc return true;
708f4a2713aSLionel Sambuc
709f4a2713aSLionel Sambuc int64_t Pow2Alignment = 0;
710f4a2713aSLionel Sambuc SMLoc Pow2AlignmentLoc;
711f4a2713aSLionel Sambuc if (getLexer().is(AsmToken::Comma)) {
712f4a2713aSLionel Sambuc Lex();
713f4a2713aSLionel Sambuc Pow2AlignmentLoc = getLexer().getLoc();
714f4a2713aSLionel Sambuc if (getParser().parseAbsoluteExpression(Pow2Alignment))
715f4a2713aSLionel Sambuc return true;
716f4a2713aSLionel Sambuc }
717f4a2713aSLionel Sambuc
718f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
719f4a2713aSLionel Sambuc return TokError("unexpected token in '.tbss' directive");
720f4a2713aSLionel Sambuc
721f4a2713aSLionel Sambuc Lex();
722f4a2713aSLionel Sambuc
723f4a2713aSLionel Sambuc if (Size < 0)
724f4a2713aSLionel Sambuc return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
725f4a2713aSLionel Sambuc "zero");
726f4a2713aSLionel Sambuc
727f4a2713aSLionel Sambuc // FIXME: Diagnose overflow.
728f4a2713aSLionel Sambuc if (Pow2Alignment < 0)
729f4a2713aSLionel Sambuc return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
730f4a2713aSLionel Sambuc "than zero");
731f4a2713aSLionel Sambuc
732f4a2713aSLionel Sambuc if (!Sym->isUndefined())
733f4a2713aSLionel Sambuc return Error(IDLoc, "invalid symbol redefinition");
734f4a2713aSLionel Sambuc
735f4a2713aSLionel Sambuc getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
736f4a2713aSLionel Sambuc "__DATA", "__thread_bss",
737*0a6a1f1dSLionel Sambuc MachO::S_THREAD_LOCAL_ZEROFILL,
738f4a2713aSLionel Sambuc 0, SectionKind::getThreadBSS()),
739f4a2713aSLionel Sambuc Sym, Size, 1 << Pow2Alignment);
740f4a2713aSLionel Sambuc
741f4a2713aSLionel Sambuc return false;
742f4a2713aSLionel Sambuc }
743f4a2713aSLionel Sambuc
744f4a2713aSLionel Sambuc /// ParseDirectiveZerofill
745f4a2713aSLionel Sambuc /// ::= .zerofill segname , sectname [, identifier , size_expression [
746f4a2713aSLionel Sambuc /// , align_expression ]]
parseDirectiveZerofill(StringRef,SMLoc)747*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
748f4a2713aSLionel Sambuc StringRef Segment;
749f4a2713aSLionel Sambuc if (getParser().parseIdentifier(Segment))
750f4a2713aSLionel Sambuc return TokError("expected segment name after '.zerofill' directive");
751f4a2713aSLionel Sambuc
752f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::Comma))
753f4a2713aSLionel Sambuc return TokError("unexpected token in directive");
754f4a2713aSLionel Sambuc Lex();
755f4a2713aSLionel Sambuc
756f4a2713aSLionel Sambuc StringRef Section;
757f4a2713aSLionel Sambuc if (getParser().parseIdentifier(Section))
758f4a2713aSLionel Sambuc return TokError("expected section name after comma in '.zerofill' "
759f4a2713aSLionel Sambuc "directive");
760f4a2713aSLionel Sambuc
761f4a2713aSLionel Sambuc // If this is the end of the line all that was wanted was to create the
762f4a2713aSLionel Sambuc // the section but with no symbol.
763f4a2713aSLionel Sambuc if (getLexer().is(AsmToken::EndOfStatement)) {
764f4a2713aSLionel Sambuc // Create the zerofill section but no symbol
765f4a2713aSLionel Sambuc getStreamer().EmitZerofill(getContext().getMachOSection(
766*0a6a1f1dSLionel Sambuc Segment, Section, MachO::S_ZEROFILL,
767f4a2713aSLionel Sambuc 0, SectionKind::getBSS()));
768f4a2713aSLionel Sambuc return false;
769f4a2713aSLionel Sambuc }
770f4a2713aSLionel Sambuc
771f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::Comma))
772f4a2713aSLionel Sambuc return TokError("unexpected token in directive");
773f4a2713aSLionel Sambuc Lex();
774f4a2713aSLionel Sambuc
775f4a2713aSLionel Sambuc SMLoc IDLoc = getLexer().getLoc();
776f4a2713aSLionel Sambuc StringRef IDStr;
777f4a2713aSLionel Sambuc if (getParser().parseIdentifier(IDStr))
778f4a2713aSLionel Sambuc return TokError("expected identifier in directive");
779f4a2713aSLionel Sambuc
780f4a2713aSLionel Sambuc // handle the identifier as the key symbol.
781f4a2713aSLionel Sambuc MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
782f4a2713aSLionel Sambuc
783f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::Comma))
784f4a2713aSLionel Sambuc return TokError("unexpected token in directive");
785f4a2713aSLionel Sambuc Lex();
786f4a2713aSLionel Sambuc
787f4a2713aSLionel Sambuc int64_t Size;
788f4a2713aSLionel Sambuc SMLoc SizeLoc = getLexer().getLoc();
789f4a2713aSLionel Sambuc if (getParser().parseAbsoluteExpression(Size))
790f4a2713aSLionel Sambuc return true;
791f4a2713aSLionel Sambuc
792f4a2713aSLionel Sambuc int64_t Pow2Alignment = 0;
793f4a2713aSLionel Sambuc SMLoc Pow2AlignmentLoc;
794f4a2713aSLionel Sambuc if (getLexer().is(AsmToken::Comma)) {
795f4a2713aSLionel Sambuc Lex();
796f4a2713aSLionel Sambuc Pow2AlignmentLoc = getLexer().getLoc();
797f4a2713aSLionel Sambuc if (getParser().parseAbsoluteExpression(Pow2Alignment))
798f4a2713aSLionel Sambuc return true;
799f4a2713aSLionel Sambuc }
800f4a2713aSLionel Sambuc
801f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
802f4a2713aSLionel Sambuc return TokError("unexpected token in '.zerofill' directive");
803f4a2713aSLionel Sambuc
804f4a2713aSLionel Sambuc Lex();
805f4a2713aSLionel Sambuc
806f4a2713aSLionel Sambuc if (Size < 0)
807f4a2713aSLionel Sambuc return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
808f4a2713aSLionel Sambuc "than zero");
809f4a2713aSLionel Sambuc
810f4a2713aSLionel Sambuc // NOTE: The alignment in the directive is a power of 2 value, the assembler
811f4a2713aSLionel Sambuc // may internally end up wanting an alignment in bytes.
812f4a2713aSLionel Sambuc // FIXME: Diagnose overflow.
813f4a2713aSLionel Sambuc if (Pow2Alignment < 0)
814f4a2713aSLionel Sambuc return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
815f4a2713aSLionel Sambuc "can't be less than zero");
816f4a2713aSLionel Sambuc
817f4a2713aSLionel Sambuc if (!Sym->isUndefined())
818f4a2713aSLionel Sambuc return Error(IDLoc, "invalid symbol redefinition");
819f4a2713aSLionel Sambuc
820f4a2713aSLionel Sambuc // Create the zerofill Symbol with Size and Pow2Alignment
821f4a2713aSLionel Sambuc //
822f4a2713aSLionel Sambuc // FIXME: Arch specific.
823f4a2713aSLionel Sambuc getStreamer().EmitZerofill(getContext().getMachOSection(
824*0a6a1f1dSLionel Sambuc Segment, Section, MachO::S_ZEROFILL,
825f4a2713aSLionel Sambuc 0, SectionKind::getBSS()),
826f4a2713aSLionel Sambuc Sym, Size, 1 << Pow2Alignment);
827f4a2713aSLionel Sambuc
828f4a2713aSLionel Sambuc return false;
829f4a2713aSLionel Sambuc }
830f4a2713aSLionel Sambuc
831f4a2713aSLionel Sambuc /// ParseDirectiveDataRegion
832f4a2713aSLionel Sambuc /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
parseDirectiveDataRegion(StringRef,SMLoc)833*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) {
834f4a2713aSLionel Sambuc if (getLexer().is(AsmToken::EndOfStatement)) {
835f4a2713aSLionel Sambuc Lex();
836f4a2713aSLionel Sambuc getStreamer().EmitDataRegion(MCDR_DataRegion);
837f4a2713aSLionel Sambuc return false;
838f4a2713aSLionel Sambuc }
839f4a2713aSLionel Sambuc StringRef RegionType;
840f4a2713aSLionel Sambuc SMLoc Loc = getParser().getTok().getLoc();
841f4a2713aSLionel Sambuc if (getParser().parseIdentifier(RegionType))
842f4a2713aSLionel Sambuc return TokError("expected region type after '.data_region' directive");
843f4a2713aSLionel Sambuc int Kind = StringSwitch<int>(RegionType)
844f4a2713aSLionel Sambuc .Case("jt8", MCDR_DataRegionJT8)
845f4a2713aSLionel Sambuc .Case("jt16", MCDR_DataRegionJT16)
846f4a2713aSLionel Sambuc .Case("jt32", MCDR_DataRegionJT32)
847f4a2713aSLionel Sambuc .Default(-1);
848f4a2713aSLionel Sambuc if (Kind == -1)
849f4a2713aSLionel Sambuc return Error(Loc, "unknown region type in '.data_region' directive");
850f4a2713aSLionel Sambuc Lex();
851f4a2713aSLionel Sambuc
852f4a2713aSLionel Sambuc getStreamer().EmitDataRegion((MCDataRegionType)Kind);
853f4a2713aSLionel Sambuc return false;
854f4a2713aSLionel Sambuc }
855f4a2713aSLionel Sambuc
856f4a2713aSLionel Sambuc /// ParseDirectiveDataRegionEnd
857f4a2713aSLionel Sambuc /// ::= .end_data_region
parseDirectiveDataRegionEnd(StringRef,SMLoc)858*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
859f4a2713aSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement))
860f4a2713aSLionel Sambuc return TokError("unexpected token in '.end_data_region' directive");
861f4a2713aSLionel Sambuc
862f4a2713aSLionel Sambuc Lex();
863f4a2713aSLionel Sambuc getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
864f4a2713aSLionel Sambuc return false;
865f4a2713aSLionel Sambuc }
866f4a2713aSLionel Sambuc
867*0a6a1f1dSLionel Sambuc /// parseVersionMin
868*0a6a1f1dSLionel Sambuc /// ::= .ios_version_min major,minor[,update]
869*0a6a1f1dSLionel Sambuc /// ::= .macosx_version_min major,minor[,update]
parseVersionMin(StringRef Directive,SMLoc)870*0a6a1f1dSLionel Sambuc bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) {
871*0a6a1f1dSLionel Sambuc int64_t Major = 0, Minor = 0, Update = 0;
872*0a6a1f1dSLionel Sambuc int Kind = StringSwitch<int>(Directive)
873*0a6a1f1dSLionel Sambuc .Case(".ios_version_min", MCVM_IOSVersionMin)
874*0a6a1f1dSLionel Sambuc .Case(".macosx_version_min", MCVM_OSXVersionMin);
875*0a6a1f1dSLionel Sambuc // Get the major version number.
876*0a6a1f1dSLionel Sambuc if (getLexer().isNot(AsmToken::Integer))
877*0a6a1f1dSLionel Sambuc return TokError("invalid OS major version number");
878*0a6a1f1dSLionel Sambuc Major = getLexer().getTok().getIntVal();
879*0a6a1f1dSLionel Sambuc if (Major > 65535 || Major <= 0)
880*0a6a1f1dSLionel Sambuc return TokError("invalid OS major version number");
881*0a6a1f1dSLionel Sambuc Lex();
882*0a6a1f1dSLionel Sambuc if (getLexer().isNot(AsmToken::Comma))
883*0a6a1f1dSLionel Sambuc return TokError("minor OS version number required, comma expected");
884*0a6a1f1dSLionel Sambuc Lex();
885*0a6a1f1dSLionel Sambuc // Get the minor version number.
886*0a6a1f1dSLionel Sambuc if (getLexer().isNot(AsmToken::Integer))
887*0a6a1f1dSLionel Sambuc return TokError("invalid OS minor version number");
888*0a6a1f1dSLionel Sambuc Minor = getLexer().getTok().getIntVal();
889*0a6a1f1dSLionel Sambuc if (Minor > 255 || Minor < 0)
890*0a6a1f1dSLionel Sambuc return TokError("invalid OS minor version number");
891*0a6a1f1dSLionel Sambuc Lex();
892*0a6a1f1dSLionel Sambuc // Get the update level, if specified
893*0a6a1f1dSLionel Sambuc if (getLexer().isNot(AsmToken::EndOfStatement)) {
894*0a6a1f1dSLionel Sambuc if (getLexer().isNot(AsmToken::Comma))
895*0a6a1f1dSLionel Sambuc return TokError("invalid update specifier, comma expected");
896*0a6a1f1dSLionel Sambuc Lex();
897*0a6a1f1dSLionel Sambuc if (getLexer().isNot(AsmToken::Integer))
898*0a6a1f1dSLionel Sambuc return TokError("invalid OS update number");
899*0a6a1f1dSLionel Sambuc Update = getLexer().getTok().getIntVal();
900*0a6a1f1dSLionel Sambuc if (Update > 255 || Update < 0)
901*0a6a1f1dSLionel Sambuc return TokError("invalid OS update number");
902*0a6a1f1dSLionel Sambuc Lex();
903*0a6a1f1dSLionel Sambuc }
904*0a6a1f1dSLionel Sambuc
905*0a6a1f1dSLionel Sambuc // We've parsed a correct version specifier, so send it to the streamer.
906*0a6a1f1dSLionel Sambuc getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update);
907*0a6a1f1dSLionel Sambuc
908*0a6a1f1dSLionel Sambuc return false;
909*0a6a1f1dSLionel Sambuc }
910*0a6a1f1dSLionel Sambuc
911f4a2713aSLionel Sambuc namespace llvm {
912f4a2713aSLionel Sambuc
createDarwinAsmParser()913f4a2713aSLionel Sambuc MCAsmParserExtension *createDarwinAsmParser() {
914f4a2713aSLionel Sambuc return new DarwinAsmParser;
915f4a2713aSLionel Sambuc }
916f4a2713aSLionel Sambuc
917f4a2713aSLionel Sambuc } // end llvm namespace
918