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