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