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