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