xref: /minix3/external/bsd/llvm/dist/llvm/lib/MC/MCParser/DarwinAsmParser.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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