avoid copying MCAsmInfo by value, add an (extremely low prio) fixme.
[oota-llvm.git] / tools / llvm-mc / AsmParser.cpp
1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
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 // This class implements the parser for assembly files.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "AsmParser.h"
15
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCSectionMachO.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSymbol.h"
24 #include "llvm/Support/SourceMgr.h"
25 #include "llvm/Support/raw_ostream.h"
26 #include "llvm/Target/TargetAsmParser.h"
27 using namespace llvm;
28
29 // Mach-O section uniquing.
30 //
31 // FIXME: Figure out where this should live, it should be shared by
32 // TargetLoweringObjectFile.
33 typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
34
35 AsmParser::~AsmParser() {
36   // If we have the MachO uniquing map, free it.
37   delete (MachOUniqueMapTy*)SectionUniquingMap;
38 }
39
40 const MCSection *AsmParser::getMachOSection(const StringRef &Segment,
41                                             const StringRef &Section,
42                                             unsigned TypeAndAttributes,
43                                             unsigned Reserved2,
44                                             SectionKind Kind) const {
45   // We unique sections by their segment/section pair.  The returned section
46   // may not have the same flags as the requested section, if so this should be
47   // diagnosed by the client as an error.
48   
49   // Create the map if it doesn't already exist.
50   if (SectionUniquingMap == 0)
51     SectionUniquingMap = new MachOUniqueMapTy();
52   MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)SectionUniquingMap;
53   
54   // Form the name to look up.
55   SmallString<64> Name;
56   Name += Segment;
57   Name.push_back(',');
58   Name += Section;
59
60   // Do the lookup, if we have a hit, return it.
61   const MCSectionMachO *&Entry = Map[Name.str()];
62
63   // FIXME: This should validate the type and attributes.
64   if (Entry) return Entry;
65
66   // Otherwise, return a new section.
67   return Entry = MCSectionMachO::Create(Segment, Section, TypeAndAttributes,
68                                         Reserved2, Kind, Ctx);
69 }
70
71 void AsmParser::Warning(SMLoc L, const Twine &Msg) {
72   Lexer.PrintMessage(L, Msg.str(), "warning");
73 }
74
75 bool AsmParser::Error(SMLoc L, const Twine &Msg) {
76   Lexer.PrintMessage(L, Msg.str(), "error");
77   return true;
78 }
79
80 bool AsmParser::TokError(const char *Msg) {
81   Lexer.PrintMessage(Lexer.getLoc(), Msg, "error");
82   return true;
83 }
84
85 bool AsmParser::Run() {
86   // Create the initial section.
87   //
88   // FIXME: Support -n.
89   // FIXME: Target hook & command line option for initial section.
90   Out.SwitchSection(getMachOSection("__TEXT", "__text",
91                                     MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
92                                     0, SectionKind()));
93
94
95   // Prime the lexer.
96   Lexer.Lex();
97   
98   bool HadError = false;
99   
100   AsmCond StartingCondState = TheCondState;
101
102   // While we have input, parse each statement.
103   while (Lexer.isNot(AsmToken::Eof)) {
104     // Handle conditional assembly here before calling ParseStatement()
105     if (Lexer.getKind() == AsmToken::Identifier) {
106       // If we have an identifier, handle it as the key symbol.
107       AsmToken ID = Lexer.getTok();
108       SMLoc IDLoc = ID.getLoc();
109       StringRef IDVal = ID.getString();
110
111       if (IDVal == ".if" ||
112           IDVal == ".elseif" ||
113           IDVal == ".else" ||
114           IDVal == ".endif") {
115         if (!ParseConditionalAssemblyDirectives(IDVal, IDLoc))
116           continue;
117         HadError = true;
118         EatToEndOfStatement();
119         continue;
120       }
121     }
122     if (TheCondState.Ignore) {
123       EatToEndOfStatement();
124       continue;
125     }
126
127     if (!ParseStatement()) continue;
128   
129     // We had an error, remember it and recover by skipping to the next line.
130     HadError = true;
131     EatToEndOfStatement();
132   }
133
134   if (TheCondState.TheCond != StartingCondState.TheCond ||
135       TheCondState.Ignore != StartingCondState.Ignore)
136     return TokError("unmatched .ifs or .elses");
137   
138   if (!HadError)  
139     Out.Finish();
140
141   return HadError;
142 }
143
144 /// ParseConditionalAssemblyDirectives - parse the conditional assembly
145 /// directives
146 bool AsmParser::ParseConditionalAssemblyDirectives(StringRef Directive,
147                                                    SMLoc DirectiveLoc) {
148   if (Directive == ".if")
149     return ParseDirectiveIf(DirectiveLoc);
150   if (Directive == ".elseif")
151     return ParseDirectiveElseIf(DirectiveLoc);
152   if (Directive == ".else")
153     return ParseDirectiveElse(DirectiveLoc);
154   if (Directive == ".endif")
155     return ParseDirectiveEndIf(DirectiveLoc);
156   return true;
157 }
158
159 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
160 void AsmParser::EatToEndOfStatement() {
161   while (Lexer.isNot(AsmToken::EndOfStatement) &&
162          Lexer.isNot(AsmToken::Eof))
163     Lexer.Lex();
164   
165   // Eat EOL.
166   if (Lexer.is(AsmToken::EndOfStatement))
167     Lexer.Lex();
168 }
169
170
171 /// ParseParenExpr - Parse a paren expression and return it.
172 /// NOTE: This assumes the leading '(' has already been consumed.
173 ///
174 /// parenexpr ::= expr)
175 ///
176 bool AsmParser::ParseParenExpr(const MCExpr *&Res) {
177   if (ParseExpression(Res)) return true;
178   if (Lexer.isNot(AsmToken::RParen))
179     return TokError("expected ')' in parentheses expression");
180   Lexer.Lex();
181   return false;
182 }
183
184 MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
185   if (MCSymbol *S = Ctx.LookupSymbol(Name))
186     return S;
187
188   // If the label starts with L it is an assembler temporary label.
189   if (Name.startswith("L"))
190     return Ctx.CreateTemporarySymbol(Name);
191
192   return Ctx.CreateSymbol(Name);
193 }
194
195 /// ParsePrimaryExpr - Parse a primary expression and return it.
196 ///  primaryexpr ::= (parenexpr
197 ///  primaryexpr ::= symbol
198 ///  primaryexpr ::= number
199 ///  primaryexpr ::= ~,+,- primaryexpr
200 bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) {
201   switch (Lexer.getKind()) {
202   default:
203     return TokError("unknown token in expression");
204   case AsmToken::Exclaim:
205     Lexer.Lex(); // Eat the operator.
206     if (ParsePrimaryExpr(Res))
207       return true;
208     Res = MCUnaryExpr::CreateLNot(Res, getContext());
209     return false;
210   case AsmToken::String:
211   case AsmToken::Identifier:
212     // This is a label, this should be parsed as part of an expression, to
213     // handle things like LFOO+4.
214     Res = MCSymbolRefExpr::Create(Lexer.getTok().getIdentifier(), getContext());
215     Lexer.Lex(); // Eat identifier.
216     return false;
217   case AsmToken::Integer:
218     Res = MCConstantExpr::Create(Lexer.getTok().getIntVal(), getContext());
219     Lexer.Lex(); // Eat token.
220     return false;
221   case AsmToken::LParen:
222     Lexer.Lex(); // Eat the '('.
223     return ParseParenExpr(Res);
224   case AsmToken::Minus:
225     Lexer.Lex(); // Eat the operator.
226     if (ParsePrimaryExpr(Res))
227       return true;
228     Res = MCUnaryExpr::CreateMinus(Res, getContext());
229     return false;
230   case AsmToken::Plus:
231     Lexer.Lex(); // Eat the operator.
232     if (ParsePrimaryExpr(Res))
233       return true;
234     Res = MCUnaryExpr::CreatePlus(Res, getContext());
235     return false;
236   case AsmToken::Tilde:
237     Lexer.Lex(); // Eat the operator.
238     if (ParsePrimaryExpr(Res))
239       return true;
240     Res = MCUnaryExpr::CreateNot(Res, getContext());
241     return false;
242   }
243 }
244
245 /// ParseExpression - Parse an expression and return it.
246 /// 
247 ///  expr ::= expr +,- expr          -> lowest.
248 ///  expr ::= expr |,^,&,! expr      -> middle.
249 ///  expr ::= expr *,/,%,<<,>> expr  -> highest.
250 ///  expr ::= primaryexpr
251 ///
252 bool AsmParser::ParseExpression(const MCExpr *&Res) {
253   Res = 0;
254   return ParsePrimaryExpr(Res) ||
255          ParseBinOpRHS(1, Res);
256 }
257
258 bool AsmParser::ParseParenExpression(const MCExpr *&Res) {
259   if (ParseParenExpr(Res))
260     return true;
261
262   return false;
263 }
264
265 bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
266   const MCExpr *Expr;
267   
268   SMLoc StartLoc = Lexer.getLoc();
269   if (ParseExpression(Expr))
270     return true;
271
272   if (!Expr->EvaluateAsAbsolute(Ctx, Res))
273     return Error(StartLoc, "expected absolute expression");
274
275   return false;
276 }
277
278 static unsigned getBinOpPrecedence(AsmToken::TokenKind K, 
279                                    MCBinaryExpr::Opcode &Kind) {
280   switch (K) {
281   default:
282     return 0;    // not a binop.
283
284     // Lowest Precedence: &&, ||
285   case AsmToken::AmpAmp:
286     Kind = MCBinaryExpr::LAnd;
287     return 1;
288   case AsmToken::PipePipe:
289     Kind = MCBinaryExpr::LOr;
290     return 1;
291
292     // Low Precedence: +, -, ==, !=, <>, <, <=, >, >=
293   case AsmToken::Plus:
294     Kind = MCBinaryExpr::Add;
295     return 2;
296   case AsmToken::Minus:
297     Kind = MCBinaryExpr::Sub;
298     return 2;
299   case AsmToken::EqualEqual:
300     Kind = MCBinaryExpr::EQ;
301     return 2;
302   case AsmToken::ExclaimEqual:
303   case AsmToken::LessGreater:
304     Kind = MCBinaryExpr::NE;
305     return 2;
306   case AsmToken::Less:
307     Kind = MCBinaryExpr::LT;
308     return 2;
309   case AsmToken::LessEqual:
310     Kind = MCBinaryExpr::LTE;
311     return 2;
312   case AsmToken::Greater:
313     Kind = MCBinaryExpr::GT;
314     return 2;
315   case AsmToken::GreaterEqual:
316     Kind = MCBinaryExpr::GTE;
317     return 2;
318
319     // Intermediate Precedence: |, &, ^
320     //
321     // FIXME: gas seems to support '!' as an infix operator?
322   case AsmToken::Pipe:
323     Kind = MCBinaryExpr::Or;
324     return 3;
325   case AsmToken::Caret:
326     Kind = MCBinaryExpr::Xor;
327     return 3;
328   case AsmToken::Amp:
329     Kind = MCBinaryExpr::And;
330     return 3;
331
332     // Highest Precedence: *, /, %, <<, >>
333   case AsmToken::Star:
334     Kind = MCBinaryExpr::Mul;
335     return 4;
336   case AsmToken::Slash:
337     Kind = MCBinaryExpr::Div;
338     return 4;
339   case AsmToken::Percent:
340     Kind = MCBinaryExpr::Mod;
341     return 4;
342   case AsmToken::LessLess:
343     Kind = MCBinaryExpr::Shl;
344     return 4;
345   case AsmToken::GreaterGreater:
346     Kind = MCBinaryExpr::Shr;
347     return 4;
348   }
349 }
350
351
352 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
353 /// Res contains the LHS of the expression on input.
354 bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res) {
355   while (1) {
356     MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
357     unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
358     
359     // If the next token is lower precedence than we are allowed to eat, return
360     // successfully with what we ate already.
361     if (TokPrec < Precedence)
362       return false;
363     
364     Lexer.Lex();
365     
366     // Eat the next primary expression.
367     const MCExpr *RHS;
368     if (ParsePrimaryExpr(RHS)) return true;
369     
370     // If BinOp binds less tightly with RHS than the operator after RHS, let
371     // the pending operator take RHS as its LHS.
372     MCBinaryExpr::Opcode Dummy;
373     unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
374     if (TokPrec < NextTokPrec) {
375       if (ParseBinOpRHS(Precedence+1, RHS)) return true;
376     }
377
378     // Merge LHS and RHS according to operator.
379     Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
380   }
381 }
382
383   
384   
385   
386 /// ParseStatement:
387 ///   ::= EndOfStatement
388 ///   ::= Label* Directive ...Operands... EndOfStatement
389 ///   ::= Label* Identifier OperandList* EndOfStatement
390 bool AsmParser::ParseStatement() {
391   if (Lexer.is(AsmToken::EndOfStatement)) {
392     Lexer.Lex();
393     return false;
394   }
395
396   // Statements always start with an identifier.
397   AsmToken ID = Lexer.getTok();
398   SMLoc IDLoc = ID.getLoc();
399   StringRef IDVal;
400   if (ParseIdentifier(IDVal))
401     return TokError("unexpected token at start of statement");
402
403   // FIXME: Recurse on local labels?
404
405   // See what kind of statement we have.
406   switch (Lexer.getKind()) {
407   case AsmToken::Colon: {
408     // identifier ':'   -> Label.
409     Lexer.Lex();
410
411     // Diagnose attempt to use a variable as a label.
412     //
413     // FIXME: Diagnostics. Note the location of the definition as a label.
414     // FIXME: This doesn't diagnose assignment to a symbol which has been
415     // implicitly marked as external.
416     MCSymbol *Sym = CreateSymbol(IDVal);
417     if (!Sym->isUndefined())
418       return Error(IDLoc, "invalid symbol redefinition");
419     
420     // Emit the label.
421     Out.EmitLabel(Sym);
422    
423     return ParseStatement();
424   }
425
426   case AsmToken::Equal:
427     // identifier '=' ... -> assignment statement
428     Lexer.Lex();
429
430     return ParseAssignment(IDVal);
431
432   default: // Normal instruction or directive.
433     break;
434   }
435   
436   // Otherwise, we have a normal instruction or directive.  
437   if (IDVal[0] == '.') {
438     // FIXME: This should be driven based on a hash lookup and callback.
439     if (IDVal == ".section")
440       return ParseDirectiveDarwinSection();
441     if (IDVal == ".text")
442       // FIXME: This changes behavior based on the -static flag to the
443       // assembler.
444       return ParseDirectiveSectionSwitch("__TEXT", "__text",
445                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
446     if (IDVal == ".const")
447       return ParseDirectiveSectionSwitch("__TEXT", "__const");
448     if (IDVal == ".static_const")
449       return ParseDirectiveSectionSwitch("__TEXT", "__static_const");
450     if (IDVal == ".cstring")
451       return ParseDirectiveSectionSwitch("__TEXT","__cstring", 
452                                          MCSectionMachO::S_CSTRING_LITERALS);
453     if (IDVal == ".literal4")
454       return ParseDirectiveSectionSwitch("__TEXT", "__literal4",
455                                          MCSectionMachO::S_4BYTE_LITERALS,
456                                          4);
457     if (IDVal == ".literal8")
458       return ParseDirectiveSectionSwitch("__TEXT", "__literal8",
459                                          MCSectionMachO::S_8BYTE_LITERALS,
460                                          8);
461     if (IDVal == ".literal16")
462       return ParseDirectiveSectionSwitch("__TEXT","__literal16",
463                                          MCSectionMachO::S_16BYTE_LITERALS,
464                                          16);
465     if (IDVal == ".constructor")
466       return ParseDirectiveSectionSwitch("__TEXT","__constructor");
467     if (IDVal == ".destructor")
468       return ParseDirectiveSectionSwitch("__TEXT","__destructor");
469     if (IDVal == ".fvmlib_init0")
470       return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0");
471     if (IDVal == ".fvmlib_init1")
472       return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1");
473
474     // FIXME: The assembler manual claims that this has the self modify code
475     // flag, at least on x86-32, but that does not appear to be correct.
476     if (IDVal == ".symbol_stub")
477       return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub",
478                                          MCSectionMachO::S_SYMBOL_STUBS |
479                                        MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
480                                           // FIXME: Different on PPC and ARM.
481                                          0, 16);
482     // FIXME: PowerPC only?
483     if (IDVal == ".picsymbol_stub")
484       return ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub",
485                                          MCSectionMachO::S_SYMBOL_STUBS |
486                                        MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
487                                          0, 26);
488     if (IDVal == ".data")
489       return ParseDirectiveSectionSwitch("__DATA", "__data");
490     if (IDVal == ".static_data")
491       return ParseDirectiveSectionSwitch("__DATA", "__static_data");
492
493     // FIXME: The section names of these two are misspelled in the assembler
494     // manual.
495     if (IDVal == ".non_lazy_symbol_pointer")
496       return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_ptr",
497                                      MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
498                                          4);
499     if (IDVal == ".lazy_symbol_pointer")
500       return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_ptr",
501                                          MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
502                                          4);
503
504     if (IDVal == ".dyld")
505       return ParseDirectiveSectionSwitch("__DATA", "__dyld");
506     if (IDVal == ".mod_init_func")
507       return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func",
508                                        MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
509                                          4);
510     if (IDVal == ".mod_term_func")
511       return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func",
512                                        MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
513                                          4);
514     if (IDVal == ".const_data")
515       return ParseDirectiveSectionSwitch("__DATA", "__const");
516     
517     
518     if (IDVal == ".objc_class")
519       return ParseDirectiveSectionSwitch("__OBJC", "__class", 
520                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
521     if (IDVal == ".objc_meta_class")
522       return ParseDirectiveSectionSwitch("__OBJC", "__meta_class",
523                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
524     if (IDVal == ".objc_cat_cls_meth")
525       return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth",
526                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
527     if (IDVal == ".objc_cat_inst_meth")
528       return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth",
529                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
530     if (IDVal == ".objc_protocol")
531       return ParseDirectiveSectionSwitch("__OBJC", "__protocol",
532                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
533     if (IDVal == ".objc_string_object")
534       return ParseDirectiveSectionSwitch("__OBJC", "__string_object",
535                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
536     if (IDVal == ".objc_cls_meth")
537       return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth",
538                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
539     if (IDVal == ".objc_inst_meth")
540       return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth",
541                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
542     if (IDVal == ".objc_cls_refs")
543       return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs",
544                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
545                                          MCSectionMachO::S_LITERAL_POINTERS,
546                                          4);
547     if (IDVal == ".objc_message_refs")
548       return ParseDirectiveSectionSwitch("__OBJC", "__message_refs",
549                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
550                                          MCSectionMachO::S_LITERAL_POINTERS,
551                                          4);
552     if (IDVal == ".objc_symbols")
553       return ParseDirectiveSectionSwitch("__OBJC", "__symbols",
554                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
555     if (IDVal == ".objc_category")
556       return ParseDirectiveSectionSwitch("__OBJC", "__category",
557                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
558     if (IDVal == ".objc_class_vars")
559       return ParseDirectiveSectionSwitch("__OBJC", "__class_vars",
560                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
561     if (IDVal == ".objc_instance_vars")
562       return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars",
563                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
564     if (IDVal == ".objc_module_info")
565       return ParseDirectiveSectionSwitch("__OBJC", "__module_info",
566                                          MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
567     if (IDVal == ".objc_class_names")
568       return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
569                                          MCSectionMachO::S_CSTRING_LITERALS);
570     if (IDVal == ".objc_meth_var_types")
571       return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
572                                          MCSectionMachO::S_CSTRING_LITERALS);
573     if (IDVal == ".objc_meth_var_names")
574       return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
575                                          MCSectionMachO::S_CSTRING_LITERALS);
576     if (IDVal == ".objc_selector_strs")
577       return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs",
578                                          MCSectionMachO::S_CSTRING_LITERALS);
579     
580     // Assembler features
581     if (IDVal == ".set")
582       return ParseDirectiveSet();
583
584     // Data directives
585
586     if (IDVal == ".ascii")
587       return ParseDirectiveAscii(false);
588     if (IDVal == ".asciz")
589       return ParseDirectiveAscii(true);
590
591     if (IDVal == ".byte")
592       return ParseDirectiveValue(1);
593     if (IDVal == ".short")
594       return ParseDirectiveValue(2);
595     if (IDVal == ".long")
596       return ParseDirectiveValue(4);
597     if (IDVal == ".quad")
598       return ParseDirectiveValue(8);
599
600     // FIXME: Target hooks for IsPow2.
601     if (IDVal == ".align")
602       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
603     if (IDVal == ".align32")
604       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
605     if (IDVal == ".balign")
606       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
607     if (IDVal == ".balignw")
608       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
609     if (IDVal == ".balignl")
610       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
611     if (IDVal == ".p2align")
612       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
613     if (IDVal == ".p2alignw")
614       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
615     if (IDVal == ".p2alignl")
616       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
617
618     if (IDVal == ".org")
619       return ParseDirectiveOrg();
620
621     if (IDVal == ".fill")
622       return ParseDirectiveFill();
623     if (IDVal == ".space")
624       return ParseDirectiveSpace();
625
626     // Symbol attribute directives
627
628     if (IDVal == ".globl" || IDVal == ".global")
629       return ParseDirectiveSymbolAttribute(MCStreamer::Global);
630     if (IDVal == ".hidden")
631       return ParseDirectiveSymbolAttribute(MCStreamer::Hidden);
632     if (IDVal == ".indirect_symbol")
633       return ParseDirectiveSymbolAttribute(MCStreamer::IndirectSymbol);
634     if (IDVal == ".internal")
635       return ParseDirectiveSymbolAttribute(MCStreamer::Internal);
636     if (IDVal == ".lazy_reference")
637       return ParseDirectiveSymbolAttribute(MCStreamer::LazyReference);
638     if (IDVal == ".no_dead_strip")
639       return ParseDirectiveSymbolAttribute(MCStreamer::NoDeadStrip);
640     if (IDVal == ".private_extern")
641       return ParseDirectiveSymbolAttribute(MCStreamer::PrivateExtern);
642     if (IDVal == ".protected")
643       return ParseDirectiveSymbolAttribute(MCStreamer::Protected);
644     if (IDVal == ".reference")
645       return ParseDirectiveSymbolAttribute(MCStreamer::Reference);
646     if (IDVal == ".weak")
647       return ParseDirectiveSymbolAttribute(MCStreamer::Weak);
648     if (IDVal == ".weak_definition")
649       return ParseDirectiveSymbolAttribute(MCStreamer::WeakDefinition);
650     if (IDVal == ".weak_reference")
651       return ParseDirectiveSymbolAttribute(MCStreamer::WeakReference);
652
653     if (IDVal == ".comm")
654       return ParseDirectiveComm(/*IsLocal=*/false);
655     if (IDVal == ".lcomm")
656       return ParseDirectiveComm(/*IsLocal=*/true);
657     if (IDVal == ".zerofill")
658       return ParseDirectiveDarwinZerofill();
659     if (IDVal == ".desc")
660       return ParseDirectiveDarwinSymbolDesc();
661     if (IDVal == ".lsym")
662       return ParseDirectiveDarwinLsym();
663
664     if (IDVal == ".subsections_via_symbols")
665       return ParseDirectiveDarwinSubsectionsViaSymbols();
666     if (IDVal == ".abort")
667       return ParseDirectiveAbort();
668     if (IDVal == ".include")
669       return ParseDirectiveInclude();
670     if (IDVal == ".dump")
671       return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true);
672     if (IDVal == ".load")
673       return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false);
674
675     // Debugging directives
676
677     if (IDVal == ".file")
678       return ParseDirectiveFile(IDLoc);
679     if (IDVal == ".line")
680       return ParseDirectiveLine(IDLoc);
681     if (IDVal == ".loc")
682       return ParseDirectiveLoc(IDLoc);
683
684     // Target hook for parsing target specific directives.
685     if (!getTargetParser().ParseDirective(ID))
686       return false;
687
688     Warning(IDLoc, "ignoring directive for now");
689     EatToEndOfStatement();
690     return false;
691   }
692
693   MCInst Inst;
694   if (getTargetParser().ParseInstruction(IDVal, Inst))
695     return true;
696   
697   if (Lexer.isNot(AsmToken::EndOfStatement))
698     return TokError("unexpected token in argument list");
699
700   // Eat the end of statement marker.
701   Lexer.Lex();
702   
703   // Instruction is good, process it.
704   Out.EmitInstruction(Inst);
705   
706   // Skip to end of line for now.
707   return false;
708 }
709
710 bool AsmParser::ParseAssignment(const StringRef &Name) {
711   // FIXME: Use better location, we should use proper tokens.
712   SMLoc EqualLoc = Lexer.getLoc();
713
714   const MCExpr *Value;
715   SMLoc StartLoc = Lexer.getLoc();
716   if (ParseExpression(Value))
717     return true;
718   
719   if (Lexer.isNot(AsmToken::EndOfStatement))
720     return TokError("unexpected token in assignment");
721
722   // Eat the end of statement marker.
723   Lexer.Lex();
724
725   // Diagnose assignment to a label.
726   //
727   // FIXME: Diagnostics. Note the location of the definition as a label.
728   // FIXME: Handle '.'.
729   // FIXME: Diagnose assignment to protected identifier (e.g., register name).
730   MCSymbol *Sym = CreateSymbol(Name);
731   if (!Sym->isUndefined() && !Sym->isAbsolute())
732     return Error(EqualLoc, "symbol has already been defined");
733
734   // Do the assignment.
735   Out.EmitAssignment(Sym, Value);
736
737   return false;
738 }
739
740 /// ParseIdentifier:
741 ///   ::= identifier
742 ///   ::= string
743 bool AsmParser::ParseIdentifier(StringRef &Res) {
744   if (Lexer.isNot(AsmToken::Identifier) &&
745       Lexer.isNot(AsmToken::String))
746     return true;
747
748   Res = Lexer.getTok().getIdentifier();
749
750   Lexer.Lex(); // Consume the identifier token.
751
752   return false;
753 }
754
755 /// ParseDirectiveSet:
756 ///   ::= .set identifier ',' expression
757 bool AsmParser::ParseDirectiveSet() {
758   StringRef Name;
759
760   if (ParseIdentifier(Name))
761     return TokError("expected identifier after '.set' directive");
762   
763   if (Lexer.isNot(AsmToken::Comma))
764     return TokError("unexpected token in '.set'");
765   Lexer.Lex();
766
767   return ParseAssignment(Name);
768 }
769
770 /// ParseDirectiveSection:
771 ///   ::= .section identifier (',' identifier)*
772 /// FIXME: This should actually parse out the segment, section, attributes and
773 /// sizeof_stub fields.
774 bool AsmParser::ParseDirectiveDarwinSection() {
775   SMLoc Loc = Lexer.getLoc();
776
777   StringRef SectionName;
778   if (ParseIdentifier(SectionName))
779     return Error(Loc, "expected identifier after '.section' directive");
780
781   // Verify there is a following comma.
782   if (!Lexer.is(AsmToken::Comma))
783     return TokError("unexpected token in '.section' directive");
784
785   std::string SectionSpec = SectionName;
786   SectionSpec += ",";
787
788   // Add all the tokens until the end of the line, ParseSectionSpecifier will
789   // handle this.
790   StringRef EOL = Lexer.LexUntilEndOfStatement();
791   SectionSpec.append(EOL.begin(), EOL.end());
792
793   Lexer.Lex();
794   if (Lexer.isNot(AsmToken::EndOfStatement))
795     return TokError("unexpected token in '.section' directive");
796   Lexer.Lex();
797
798
799   StringRef Segment, Section;
800   unsigned TAA, StubSize;
801   std::string ErrorStr = 
802     MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
803                                           TAA, StubSize);
804   
805   if (!ErrorStr.empty())
806     return Error(Loc, ErrorStr.c_str());
807   
808   // FIXME: Arch specific.
809   Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
810                                     SectionKind()));
811   return false;
812 }
813
814 /// ParseDirectiveSectionSwitch - 
815 bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
816                                             const char *Section,
817                                             unsigned TAA, unsigned Align,
818                                             unsigned StubSize) {
819   if (Lexer.isNot(AsmToken::EndOfStatement))
820     return TokError("unexpected token in section switching directive");
821   Lexer.Lex();
822   
823   // FIXME: Arch specific.
824   Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
825                                     SectionKind()));
826
827   // Set the implicit alignment, if any.
828   //
829   // FIXME: This isn't really what 'as' does; I think it just uses the implicit
830   // alignment on the section (e.g., if one manually inserts bytes into the
831   // section, then just issueing the section switch directive will not realign
832   // the section. However, this is arguably more reasonable behavior, and there
833   // is no good reason for someone to intentionally emit incorrectly sized
834   // values into the implicitly aligned sections.
835   if (Align)
836     Out.EmitValueToAlignment(Align, 0, 1, 0);
837
838   return false;
839 }
840
841 bool AsmParser::ParseEscapedString(std::string &Data) {
842   assert(Lexer.is(AsmToken::String) && "Unexpected current token!");
843
844   Data = "";
845   StringRef Str = Lexer.getTok().getStringContents();
846   for (unsigned i = 0, e = Str.size(); i != e; ++i) {
847     if (Str[i] != '\\') {
848       Data += Str[i];
849       continue;
850     }
851
852     // Recognize escaped characters. Note that this escape semantics currently
853     // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
854     ++i;
855     if (i == e)
856       return TokError("unexpected backslash at end of string");
857
858     // Recognize octal sequences.
859     if ((unsigned) (Str[i] - '0') <= 7) {
860       // Consume up to three octal characters.
861       unsigned Value = Str[i] - '0';
862
863       if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
864         ++i;
865         Value = Value * 8 + (Str[i] - '0');
866
867         if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
868           ++i;
869           Value = Value * 8 + (Str[i] - '0');
870         }
871       }
872
873       if (Value > 255)
874         return TokError("invalid octal escape sequence (out of range)");
875
876       Data += (unsigned char) Value;
877       continue;
878     }
879
880     // Otherwise recognize individual escapes.
881     switch (Str[i]) {
882     default:
883       // Just reject invalid escape sequences for now.
884       return TokError("invalid escape sequence (unrecognized character)");
885
886     case 'b': Data += '\b'; break;
887     case 'f': Data += '\f'; break;
888     case 'n': Data += '\n'; break;
889     case 'r': Data += '\r'; break;
890     case 't': Data += '\t'; break;
891     case '"': Data += '"'; break;
892     case '\\': Data += '\\'; break;
893     }
894   }
895
896   return false;
897 }
898
899 /// ParseDirectiveAscii:
900 ///   ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ]
901 bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
902   if (Lexer.isNot(AsmToken::EndOfStatement)) {
903     for (;;) {
904       if (Lexer.isNot(AsmToken::String))
905         return TokError("expected string in '.ascii' or '.asciz' directive");
906       
907       std::string Data;
908       if (ParseEscapedString(Data))
909         return true;
910       
911       Out.EmitBytes(Data);
912       if (ZeroTerminated)
913         Out.EmitBytes(StringRef("\0", 1));
914       
915       Lexer.Lex();
916       
917       if (Lexer.is(AsmToken::EndOfStatement))
918         break;
919
920       if (Lexer.isNot(AsmToken::Comma))
921         return TokError("unexpected token in '.ascii' or '.asciz' directive");
922       Lexer.Lex();
923     }
924   }
925
926   Lexer.Lex();
927   return false;
928 }
929
930 /// ParseDirectiveValue
931 ///  ::= (.byte | .short | ... ) [ expression (, expression)* ]
932 bool AsmParser::ParseDirectiveValue(unsigned Size) {
933   if (Lexer.isNot(AsmToken::EndOfStatement)) {
934     for (;;) {
935       const MCExpr *Value;
936       SMLoc StartLoc = Lexer.getLoc();
937       if (ParseExpression(Value))
938         return true;
939
940       Out.EmitValue(Value, Size);
941
942       if (Lexer.is(AsmToken::EndOfStatement))
943         break;
944       
945       // FIXME: Improve diagnostic.
946       if (Lexer.isNot(AsmToken::Comma))
947         return TokError("unexpected token in directive");
948       Lexer.Lex();
949     }
950   }
951
952   Lexer.Lex();
953   return false;
954 }
955
956 /// ParseDirectiveSpace
957 ///  ::= .space expression [ , expression ]
958 bool AsmParser::ParseDirectiveSpace() {
959   int64_t NumBytes;
960   if (ParseAbsoluteExpression(NumBytes))
961     return true;
962
963   int64_t FillExpr = 0;
964   bool HasFillExpr = false;
965   if (Lexer.isNot(AsmToken::EndOfStatement)) {
966     if (Lexer.isNot(AsmToken::Comma))
967       return TokError("unexpected token in '.space' directive");
968     Lexer.Lex();
969     
970     if (ParseAbsoluteExpression(FillExpr))
971       return true;
972
973     HasFillExpr = true;
974
975     if (Lexer.isNot(AsmToken::EndOfStatement))
976       return TokError("unexpected token in '.space' directive");
977   }
978
979   Lexer.Lex();
980
981   if (NumBytes <= 0)
982     return TokError("invalid number of bytes in '.space' directive");
983
984   // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
985   for (uint64_t i = 0, e = NumBytes; i != e; ++i)
986     Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), 1);
987
988   return false;
989 }
990
991 /// ParseDirectiveFill
992 ///  ::= .fill expression , expression , expression
993 bool AsmParser::ParseDirectiveFill() {
994   int64_t NumValues;
995   if (ParseAbsoluteExpression(NumValues))
996     return true;
997
998   if (Lexer.isNot(AsmToken::Comma))
999     return TokError("unexpected token in '.fill' directive");
1000   Lexer.Lex();
1001   
1002   int64_t FillSize;
1003   if (ParseAbsoluteExpression(FillSize))
1004     return true;
1005
1006   if (Lexer.isNot(AsmToken::Comma))
1007     return TokError("unexpected token in '.fill' directive");
1008   Lexer.Lex();
1009   
1010   int64_t FillExpr;
1011   if (ParseAbsoluteExpression(FillExpr))
1012     return true;
1013
1014   if (Lexer.isNot(AsmToken::EndOfStatement))
1015     return TokError("unexpected token in '.fill' directive");
1016   
1017   Lexer.Lex();
1018
1019   if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
1020     return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
1021
1022   for (uint64_t i = 0, e = NumValues; i != e; ++i)
1023     Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), FillSize);
1024
1025   return false;
1026 }
1027
1028 /// ParseDirectiveOrg
1029 ///  ::= .org expression [ , expression ]
1030 bool AsmParser::ParseDirectiveOrg() {
1031   const MCExpr *Offset;
1032   SMLoc StartLoc = Lexer.getLoc();
1033   if (ParseExpression(Offset))
1034     return true;
1035
1036   // Parse optional fill expression.
1037   int64_t FillExpr = 0;
1038   if (Lexer.isNot(AsmToken::EndOfStatement)) {
1039     if (Lexer.isNot(AsmToken::Comma))
1040       return TokError("unexpected token in '.org' directive");
1041     Lexer.Lex();
1042     
1043     if (ParseAbsoluteExpression(FillExpr))
1044       return true;
1045
1046     if (Lexer.isNot(AsmToken::EndOfStatement))
1047       return TokError("unexpected token in '.org' directive");
1048   }
1049
1050   Lexer.Lex();
1051
1052   // FIXME: Only limited forms of relocatable expressions are accepted here, it
1053   // has to be relative to the current section.
1054   Out.EmitValueToOffset(Offset, FillExpr);
1055
1056   return false;
1057 }
1058
1059 /// ParseDirectiveAlign
1060 ///  ::= {.align, ...} expression [ , expression [ , expression ]]
1061 bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
1062   SMLoc AlignmentLoc = Lexer.getLoc();
1063   int64_t Alignment;
1064   if (ParseAbsoluteExpression(Alignment))
1065     return true;
1066
1067   SMLoc MaxBytesLoc;
1068   bool HasFillExpr = false;
1069   int64_t FillExpr = 0;
1070   int64_t MaxBytesToFill = 0;
1071   if (Lexer.isNot(AsmToken::EndOfStatement)) {
1072     if (Lexer.isNot(AsmToken::Comma))
1073       return TokError("unexpected token in directive");
1074     Lexer.Lex();
1075
1076     // The fill expression can be omitted while specifying a maximum number of
1077     // alignment bytes, e.g:
1078     //  .align 3,,4
1079     if (Lexer.isNot(AsmToken::Comma)) {
1080       HasFillExpr = true;
1081       if (ParseAbsoluteExpression(FillExpr))
1082         return true;
1083     }
1084
1085     if (Lexer.isNot(AsmToken::EndOfStatement)) {
1086       if (Lexer.isNot(AsmToken::Comma))
1087         return TokError("unexpected token in directive");
1088       Lexer.Lex();
1089
1090       MaxBytesLoc = Lexer.getLoc();
1091       if (ParseAbsoluteExpression(MaxBytesToFill))
1092         return true;
1093       
1094       if (Lexer.isNot(AsmToken::EndOfStatement))
1095         return TokError("unexpected token in directive");
1096     }
1097   }
1098
1099   Lexer.Lex();
1100
1101   if (!HasFillExpr) {
1102     // FIXME: Sometimes fill with nop.
1103     FillExpr = 0;
1104   }
1105
1106   // Compute alignment in bytes.
1107   if (IsPow2) {
1108     // FIXME: Diagnose overflow.
1109     if (Alignment >= 32) {
1110       Error(AlignmentLoc, "invalid alignment value");
1111       Alignment = 31;
1112     }
1113
1114     Alignment = 1ULL << Alignment;
1115   }
1116
1117   // Diagnose non-sensical max bytes to align.
1118   if (MaxBytesLoc.isValid()) {
1119     if (MaxBytesToFill < 1) {
1120       Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
1121             "many bytes, ignoring maximum bytes expression");
1122       MaxBytesToFill = 0;
1123     }
1124
1125     if (MaxBytesToFill >= Alignment) {
1126       Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
1127               "has no effect");
1128       MaxBytesToFill = 0;
1129     }
1130   }
1131
1132   // FIXME: Target specific behavior about how the "extra" bytes are filled.
1133   Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
1134
1135   return false;
1136 }
1137
1138 /// ParseDirectiveSymbolAttribute
1139 ///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
1140 bool AsmParser::ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr) {
1141   if (Lexer.isNot(AsmToken::EndOfStatement)) {
1142     for (;;) {
1143       StringRef Name;
1144
1145       if (ParseIdentifier(Name))
1146         return TokError("expected identifier in directive");
1147       
1148       MCSymbol *Sym = CreateSymbol(Name);
1149
1150       Out.EmitSymbolAttribute(Sym, Attr);
1151
1152       if (Lexer.is(AsmToken::EndOfStatement))
1153         break;
1154
1155       if (Lexer.isNot(AsmToken::Comma))
1156         return TokError("unexpected token in directive");
1157       Lexer.Lex();
1158     }
1159   }
1160
1161   Lexer.Lex();
1162   return false;  
1163 }
1164
1165 /// ParseDirectiveDarwinSymbolDesc
1166 ///  ::= .desc identifier , expression
1167 bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
1168   StringRef Name;
1169   if (ParseIdentifier(Name))
1170     return TokError("expected identifier in directive");
1171   
1172   // Handle the identifier as the key symbol.
1173   MCSymbol *Sym = CreateSymbol(Name);
1174
1175   if (Lexer.isNot(AsmToken::Comma))
1176     return TokError("unexpected token in '.desc' directive");
1177   Lexer.Lex();
1178
1179   SMLoc DescLoc = Lexer.getLoc();
1180   int64_t DescValue;
1181   if (ParseAbsoluteExpression(DescValue))
1182     return true;
1183
1184   if (Lexer.isNot(AsmToken::EndOfStatement))
1185     return TokError("unexpected token in '.desc' directive");
1186   
1187   Lexer.Lex();
1188
1189   // Set the n_desc field of this Symbol to this DescValue
1190   Out.EmitSymbolDesc(Sym, DescValue);
1191
1192   return false;
1193 }
1194
1195 /// ParseDirectiveComm
1196 ///  ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
1197 bool AsmParser::ParseDirectiveComm(bool IsLocal) {
1198   SMLoc IDLoc = Lexer.getLoc();
1199   StringRef Name;
1200   if (ParseIdentifier(Name))
1201     return TokError("expected identifier in directive");
1202   
1203   // Handle the identifier as the key symbol.
1204   MCSymbol *Sym = CreateSymbol(Name);
1205
1206   if (Lexer.isNot(AsmToken::Comma))
1207     return TokError("unexpected token in directive");
1208   Lexer.Lex();
1209
1210   int64_t Size;
1211   SMLoc SizeLoc = Lexer.getLoc();
1212   if (ParseAbsoluteExpression(Size))
1213     return true;
1214
1215   int64_t Pow2Alignment = 0;
1216   SMLoc Pow2AlignmentLoc;
1217   if (Lexer.is(AsmToken::Comma)) {
1218     Lexer.Lex();
1219     Pow2AlignmentLoc = Lexer.getLoc();
1220     if (ParseAbsoluteExpression(Pow2Alignment))
1221       return true;
1222   }
1223   
1224   if (Lexer.isNot(AsmToken::EndOfStatement))
1225     return TokError("unexpected token in '.comm' or '.lcomm' directive");
1226   
1227   Lexer.Lex();
1228
1229   // NOTE: a size of zero for a .comm should create a undefined symbol
1230   // but a size of .lcomm creates a bss symbol of size zero.
1231   if (Size < 0)
1232     return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
1233                  "be less than zero");
1234
1235   // NOTE: The alignment in the directive is a power of 2 value, the assember
1236   // may internally end up wanting an alignment in bytes.
1237   // FIXME: Diagnose overflow.
1238   if (Pow2Alignment < 0)
1239     return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
1240                  "alignment, can't be less than zero");
1241
1242   if (!Sym->isUndefined())
1243     return Error(IDLoc, "invalid symbol redefinition");
1244
1245   // '.lcomm' is equivalent to '.zerofill'.
1246   // Create the Symbol as a common or local common with Size and Pow2Alignment
1247   if (IsLocal) {
1248     Out.EmitZerofill(getMachOSection("__DATA", "__bss",
1249                                      MCSectionMachO::S_ZEROFILL, 0,
1250                                      SectionKind()),
1251                      Sym, Size, 1 << Pow2Alignment);
1252     return false;
1253   }
1254
1255   Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
1256   return false;
1257 }
1258
1259 /// ParseDirectiveDarwinZerofill
1260 ///  ::= .zerofill segname , sectname [, identifier , size_expression [
1261 ///      , align_expression ]]
1262 bool AsmParser::ParseDirectiveDarwinZerofill() {
1263   // FIXME: Handle quoted names here.
1264
1265   if (Lexer.isNot(AsmToken::Identifier))
1266     return TokError("expected segment name after '.zerofill' directive");
1267   StringRef Segment = Lexer.getTok().getString();
1268   Lexer.Lex();
1269
1270   if (Lexer.isNot(AsmToken::Comma))
1271     return TokError("unexpected token in directive");
1272   Lexer.Lex();
1273  
1274   if (Lexer.isNot(AsmToken::Identifier))
1275     return TokError("expected section name after comma in '.zerofill' "
1276                     "directive");
1277   StringRef Section = Lexer.getTok().getString();
1278   Lexer.Lex();
1279
1280   // If this is the end of the line all that was wanted was to create the
1281   // the section but with no symbol.
1282   if (Lexer.is(AsmToken::EndOfStatement)) {
1283     // Create the zerofill section but no symbol
1284     Out.EmitZerofill(getMachOSection(Segment, Section,
1285                                      MCSectionMachO::S_ZEROFILL, 0,
1286                                      SectionKind()));
1287     return false;
1288   }
1289
1290   if (Lexer.isNot(AsmToken::Comma))
1291     return TokError("unexpected token in directive");
1292   Lexer.Lex();
1293
1294   if (Lexer.isNot(AsmToken::Identifier))
1295     return TokError("expected identifier in directive");
1296   
1297   // handle the identifier as the key symbol.
1298   SMLoc IDLoc = Lexer.getLoc();
1299   MCSymbol *Sym = CreateSymbol(Lexer.getTok().getString());
1300   Lexer.Lex();
1301
1302   if (Lexer.isNot(AsmToken::Comma))
1303     return TokError("unexpected token in directive");
1304   Lexer.Lex();
1305
1306   int64_t Size;
1307   SMLoc SizeLoc = Lexer.getLoc();
1308   if (ParseAbsoluteExpression(Size))
1309     return true;
1310
1311   int64_t Pow2Alignment = 0;
1312   SMLoc Pow2AlignmentLoc;
1313   if (Lexer.is(AsmToken::Comma)) {
1314     Lexer.Lex();
1315     Pow2AlignmentLoc = Lexer.getLoc();
1316     if (ParseAbsoluteExpression(Pow2Alignment))
1317       return true;
1318   }
1319   
1320   if (Lexer.isNot(AsmToken::EndOfStatement))
1321     return TokError("unexpected token in '.zerofill' directive");
1322   
1323   Lexer.Lex();
1324
1325   if (Size < 0)
1326     return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
1327                  "than zero");
1328
1329   // NOTE: The alignment in the directive is a power of 2 value, the assember
1330   // may internally end up wanting an alignment in bytes.
1331   // FIXME: Diagnose overflow.
1332   if (Pow2Alignment < 0)
1333     return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
1334                  "can't be less than zero");
1335
1336   if (!Sym->isUndefined())
1337     return Error(IDLoc, "invalid symbol redefinition");
1338
1339   // Create the zerofill Symbol with Size and Pow2Alignment
1340   //
1341   // FIXME: Arch specific.
1342   Out.EmitZerofill(getMachOSection(Segment, Section,
1343                                  MCSectionMachO::S_ZEROFILL, 0,
1344                                  SectionKind()),
1345                    Sym, Size, 1 << Pow2Alignment);
1346
1347   return false;
1348 }
1349
1350 /// ParseDirectiveDarwinSubsectionsViaSymbols
1351 ///  ::= .subsections_via_symbols
1352 bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() {
1353   if (Lexer.isNot(AsmToken::EndOfStatement))
1354     return TokError("unexpected token in '.subsections_via_symbols' directive");
1355   
1356   Lexer.Lex();
1357
1358   Out.EmitAssemblerFlag(MCStreamer::SubsectionsViaSymbols);
1359
1360   return false;
1361 }
1362
1363 /// ParseDirectiveAbort
1364 ///  ::= .abort [ "abort_string" ]
1365 bool AsmParser::ParseDirectiveAbort() {
1366   // FIXME: Use loc from directive.
1367   SMLoc Loc = Lexer.getLoc();
1368
1369   StringRef Str = "";
1370   if (Lexer.isNot(AsmToken::EndOfStatement)) {
1371     if (Lexer.isNot(AsmToken::String))
1372       return TokError("expected string in '.abort' directive");
1373     
1374     Str = Lexer.getTok().getString();
1375
1376     Lexer.Lex();
1377   }
1378
1379   if (Lexer.isNot(AsmToken::EndOfStatement))
1380     return TokError("unexpected token in '.abort' directive");
1381   
1382   Lexer.Lex();
1383
1384   // FIXME: Handle here.
1385   if (Str.empty())
1386     Error(Loc, ".abort detected. Assembly stopping.");
1387   else
1388     Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
1389
1390   return false;
1391 }
1392
1393 /// ParseDirectiveLsym
1394 ///  ::= .lsym identifier , expression
1395 bool AsmParser::ParseDirectiveDarwinLsym() {
1396   StringRef Name;
1397   if (ParseIdentifier(Name))
1398     return TokError("expected identifier in directive");
1399   
1400   // Handle the identifier as the key symbol.
1401   MCSymbol *Sym = CreateSymbol(Name);
1402
1403   if (Lexer.isNot(AsmToken::Comma))
1404     return TokError("unexpected token in '.lsym' directive");
1405   Lexer.Lex();
1406
1407   const MCExpr *Value;
1408   SMLoc StartLoc = Lexer.getLoc();
1409   if (ParseExpression(Value))
1410     return true;
1411
1412   if (Lexer.isNot(AsmToken::EndOfStatement))
1413     return TokError("unexpected token in '.lsym' directive");
1414   
1415   Lexer.Lex();
1416
1417   // We don't currently support this directive.
1418   //
1419   // FIXME: Diagnostic location!
1420   (void) Sym;
1421   return TokError("directive '.lsym' is unsupported");
1422 }
1423
1424 /// ParseDirectiveInclude
1425 ///  ::= .include "filename"
1426 bool AsmParser::ParseDirectiveInclude() {
1427   if (Lexer.isNot(AsmToken::String))
1428     return TokError("expected string in '.include' directive");
1429   
1430   std::string Filename = Lexer.getTok().getString();
1431   SMLoc IncludeLoc = Lexer.getLoc();
1432   Lexer.Lex();
1433
1434   if (Lexer.isNot(AsmToken::EndOfStatement))
1435     return TokError("unexpected token in '.include' directive");
1436   
1437   // Strip the quotes.
1438   Filename = Filename.substr(1, Filename.size()-2);
1439   
1440   // Attempt to switch the lexer to the included file before consuming the end
1441   // of statement to avoid losing it when we switch.
1442   if (Lexer.EnterIncludeFile(Filename)) {
1443     Lexer.PrintMessage(IncludeLoc,
1444                        "Could not find include file '" + Filename + "'",
1445                        "error");
1446     return true;
1447   }
1448
1449   return false;
1450 }
1451
1452 /// ParseDirectiveDarwinDumpOrLoad
1453 ///  ::= ( .dump | .load ) "filename"
1454 bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
1455   if (Lexer.isNot(AsmToken::String))
1456     return TokError("expected string in '.dump' or '.load' directive");
1457   
1458   Lexer.Lex();
1459
1460   if (Lexer.isNot(AsmToken::EndOfStatement))
1461     return TokError("unexpected token in '.dump' or '.load' directive");
1462   
1463   Lexer.Lex();
1464
1465   // FIXME: If/when .dump and .load are implemented they will be done in the
1466   // the assembly parser and not have any need for an MCStreamer API.
1467   if (IsDump)
1468     Warning(IDLoc, "ignoring directive .dump for now");
1469   else
1470     Warning(IDLoc, "ignoring directive .load for now");
1471
1472   return false;
1473 }
1474
1475 /// ParseDirectiveIf
1476 /// ::= .if expression
1477 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
1478   // Consume the identifier that was the .if directive
1479   Lexer.Lex();
1480
1481   TheCondStack.push_back(TheCondState);
1482   TheCondState.TheCond = AsmCond::IfCond;
1483   if(TheCondState.Ignore) {
1484     EatToEndOfStatement();
1485   }
1486   else {
1487     int64_t ExprValue;
1488     if (ParseAbsoluteExpression(ExprValue))
1489       return true;
1490
1491     if (Lexer.isNot(AsmToken::EndOfStatement))
1492       return TokError("unexpected token in '.if' directive");
1493     
1494     Lexer.Lex();
1495
1496     TheCondState.CondMet = ExprValue;
1497     TheCondState.Ignore = !TheCondState.CondMet;
1498   }
1499
1500   return false;
1501 }
1502
1503 /// ParseDirectiveElseIf
1504 /// ::= .elseif expression
1505 bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
1506   if (TheCondState.TheCond != AsmCond::IfCond &&
1507       TheCondState.TheCond != AsmCond::ElseIfCond)
1508       Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
1509                           " an .elseif");
1510   TheCondState.TheCond = AsmCond::ElseIfCond;
1511
1512   // Consume the identifier that was the .elseif directive
1513   Lexer.Lex();
1514
1515   bool LastIgnoreState = false;
1516   if (!TheCondStack.empty())
1517       LastIgnoreState = TheCondStack.back().Ignore;
1518   if (LastIgnoreState || TheCondState.CondMet) {
1519     TheCondState.Ignore = true;
1520     EatToEndOfStatement();
1521   }
1522   else {
1523     int64_t ExprValue;
1524     if (ParseAbsoluteExpression(ExprValue))
1525       return true;
1526
1527     if (Lexer.isNot(AsmToken::EndOfStatement))
1528       return TokError("unexpected token in '.elseif' directive");
1529     
1530     Lexer.Lex();
1531     TheCondState.CondMet = ExprValue;
1532     TheCondState.Ignore = !TheCondState.CondMet;
1533   }
1534
1535   return false;
1536 }
1537
1538 /// ParseDirectiveElse
1539 /// ::= .else
1540 bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
1541   // Consume the identifier that was the .else directive
1542   Lexer.Lex();
1543
1544   if (Lexer.isNot(AsmToken::EndOfStatement))
1545     return TokError("unexpected token in '.else' directive");
1546   
1547   Lexer.Lex();
1548
1549   if (TheCondState.TheCond != AsmCond::IfCond &&
1550       TheCondState.TheCond != AsmCond::ElseIfCond)
1551       Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
1552                           ".elseif");
1553   TheCondState.TheCond = AsmCond::ElseCond;
1554   bool LastIgnoreState = false;
1555   if (!TheCondStack.empty())
1556     LastIgnoreState = TheCondStack.back().Ignore;
1557   if (LastIgnoreState || TheCondState.CondMet)
1558     TheCondState.Ignore = true;
1559   else
1560     TheCondState.Ignore = false;
1561
1562   return false;
1563 }
1564
1565 /// ParseDirectiveEndIf
1566 /// ::= .endif
1567 bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
1568   // Consume the identifier that was the .endif directive
1569   Lexer.Lex();
1570
1571   if (Lexer.isNot(AsmToken::EndOfStatement))
1572     return TokError("unexpected token in '.endif' directive");
1573   
1574   Lexer.Lex();
1575
1576   if ((TheCondState.TheCond == AsmCond::NoCond) ||
1577       TheCondStack.empty())
1578     Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
1579                         ".else");
1580   if (!TheCondStack.empty()) {
1581     TheCondState = TheCondStack.back();
1582     TheCondStack.pop_back();
1583   }
1584
1585   return false;
1586 }
1587
1588 /// ParseDirectiveFile
1589 /// ::= .file [number] string
1590 bool AsmParser::ParseDirectiveFile(SMLoc DirectiveLoc) {
1591   // FIXME: I'm not sure what this is.
1592   int64_t FileNumber = -1;
1593   if (Lexer.is(AsmToken::Integer)) {
1594     FileNumber = Lexer.getTok().getIntVal();
1595     Lexer.Lex();
1596     
1597     if (FileNumber < 1)
1598       return TokError("file number less than one");
1599   }
1600
1601   if (Lexer.isNot(AsmToken::String))
1602     return TokError("unexpected token in '.file' directive");
1603   
1604   StringRef FileName = Lexer.getTok().getString();
1605   Lexer.Lex();
1606
1607   if (Lexer.isNot(AsmToken::EndOfStatement))
1608     return TokError("unexpected token in '.file' directive");
1609
1610   // FIXME: Do something with the .file.
1611
1612   return false;
1613 }
1614
1615 /// ParseDirectiveLine
1616 /// ::= .line [number]
1617 bool AsmParser::ParseDirectiveLine(SMLoc DirectiveLoc) {
1618   if (Lexer.isNot(AsmToken::EndOfStatement)) {
1619     if (Lexer.isNot(AsmToken::Integer))
1620       return TokError("unexpected token in '.line' directive");
1621
1622     int64_t LineNumber = Lexer.getTok().getIntVal();
1623     (void) LineNumber;
1624     Lexer.Lex();
1625
1626     // FIXME: Do something with the .line.
1627   }
1628
1629   if (Lexer.isNot(AsmToken::EndOfStatement))
1630     return TokError("unexpected token in '.file' directive");
1631
1632   return false;
1633 }
1634
1635
1636 /// ParseDirectiveLoc
1637 /// ::= .loc number [number [number]]
1638 bool AsmParser::ParseDirectiveLoc(SMLoc DirectiveLoc) {
1639   if (Lexer.isNot(AsmToken::Integer))
1640     return TokError("unexpected token in '.loc' directive");
1641
1642   // FIXME: What are these fields?
1643   int64_t FileNumber = Lexer.getTok().getIntVal();
1644   (void) FileNumber;
1645   // FIXME: Validate file.
1646
1647   Lexer.Lex();
1648   if (Lexer.isNot(AsmToken::EndOfStatement)) {
1649     if (Lexer.isNot(AsmToken::Integer))
1650       return TokError("unexpected token in '.loc' directive");
1651
1652     int64_t Param2 = Lexer.getTok().getIntVal();
1653     (void) Param2;
1654     Lexer.Lex();
1655
1656     if (Lexer.isNot(AsmToken::EndOfStatement)) {
1657       if (Lexer.isNot(AsmToken::Integer))
1658         return TokError("unexpected token in '.loc' directive");
1659
1660       int64_t Param3 = Lexer.getTok().getIntVal();
1661       (void) Param3;
1662       Lexer.Lex();
1663
1664       // FIXME: Do something with the .loc.
1665     }
1666   }
1667
1668   if (Lexer.isNot(AsmToken::EndOfStatement))
1669     return TokError("unexpected token in '.file' directive");
1670
1671   return false;
1672 }
1673