MC/AsmParser: Use Error() instead of calling PrintMessage() directly.
[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/ADT/SmallString.h"
15 #include "llvm/ADT/StringMap.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCParser/AsmCond.h"
23 #include "llvm/MC/MCParser/AsmLexer.h"
24 #include "llvm/MC/MCParser/MCAsmParser.h"
25 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
26 #include "llvm/MC/MCSectionMachO.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/Support/MemoryBuffer.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/Target/TargetAsmParser.h"
34 #include <vector>
35 using namespace llvm;
36
37 namespace {
38
39 /// \brief The concrete assembly parser instance.
40 class AsmParser : public MCAsmParser {
41   AsmParser(const AsmParser &);   // DO NOT IMPLEMENT
42   void operator=(const AsmParser &);  // DO NOT IMPLEMENT
43 private:
44   AsmLexer Lexer;
45   MCContext &Ctx;
46   MCStreamer &Out;
47   SourceMgr &SrcMgr;
48   MCAsmParserExtension *GenericParser;
49   MCAsmParserExtension *PlatformParser;
50   
51   /// This is the current buffer index we're lexing from as managed by the
52   /// SourceMgr object.
53   int CurBuffer;
54
55   AsmCond TheCondState;
56   std::vector<AsmCond> TheCondStack;
57
58   /// DirectiveMap - This is a table handlers for directives.  Each handler is
59   /// invoked after the directive identifier is read and is responsible for
60   /// parsing and validating the rest of the directive.  The handler is passed
61   /// in the directive name and the location of the directive keyword.
62   StringMap<std::pair<MCAsmParserExtension*, DirectiveHandler> > DirectiveMap;
63 public:
64   AsmParser(const Target &T, SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
65             const MCAsmInfo &MAI);
66   ~AsmParser();
67
68   virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false);
69
70   void AddDirectiveHandler(MCAsmParserExtension *Object,
71                            StringRef Directive,
72                            DirectiveHandler Handler) {
73     DirectiveMap[Directive] = std::make_pair(Object, Handler);
74   }
75
76 public:
77   /// @name MCAsmParser Interface
78   /// {
79
80   virtual SourceMgr &getSourceManager() { return SrcMgr; }
81   virtual MCAsmLexer &getLexer() { return Lexer; }
82   virtual MCContext &getContext() { return Ctx; }
83   virtual MCStreamer &getStreamer() { return Out; }
84
85   virtual void Warning(SMLoc L, const Twine &Meg);
86   virtual bool Error(SMLoc L, const Twine &Msg);
87
88   const AsmToken &Lex();
89
90   bool ParseExpression(const MCExpr *&Res);
91   virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc);
92   virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
93   virtual bool ParseAbsoluteExpression(int64_t &Res);
94
95   /// }
96
97 private:
98   bool ParseStatement();
99
100   void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type) const;
101     
102   /// EnterIncludeFile - Enter the specified file. This returns true on failure.
103   bool EnterIncludeFile(const std::string &Filename);
104   
105   void EatToEndOfStatement();
106   
107   bool ParseAssignment(StringRef Name);
108
109   bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
110   bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
111   bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
112
113   /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
114   /// and set \arg Res to the identifier contents.
115   bool ParseIdentifier(StringRef &Res);
116   
117   // Directive Parsing.
118   bool ParseDirectiveAscii(bool ZeroTerminated); // ".ascii", ".asciiz"
119   bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
120   bool ParseDirectiveFill(); // ".fill"
121   bool ParseDirectiveSpace(); // ".space"
122   bool ParseDirectiveSet(); // ".set"
123   bool ParseDirectiveOrg(); // ".org"
124   // ".align{,32}", ".p2align{,w,l}"
125   bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
126
127   /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
128   /// accepts a single symbol (which should be a label or an external).
129   bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr);
130   bool ParseDirectiveELFType(); // ELF specific ".type"
131
132   bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
133
134   bool ParseDirectiveAbort(); // ".abort"
135   bool ParseDirectiveInclude(); // ".include"
136
137   bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if"
138   bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
139   bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else"
140   bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
141
142   /// ParseEscapedString - Parse the current token as a string which may include
143   /// escaped characters and return the string contents.
144   bool ParseEscapedString(std::string &Data);
145 };
146
147 /// \brief Generic implementations of directive handling, etc. which is shared
148 /// (or the default, at least) for all assembler parser.
149 class GenericAsmParser : public MCAsmParserExtension {
150 public:
151   GenericAsmParser() {}
152
153   virtual void Initialize(MCAsmParser &Parser) {
154     // Call the base implementation.
155     this->MCAsmParserExtension::Initialize(Parser);
156
157     // Debugging directives.
158     Parser.AddDirectiveHandler(this, ".file", MCAsmParser::DirectiveHandler(
159                                  &GenericAsmParser::ParseDirectiveFile));
160     Parser.AddDirectiveHandler(this, ".line", MCAsmParser::DirectiveHandler(
161                                  &GenericAsmParser::ParseDirectiveLine));
162     Parser.AddDirectiveHandler(this, ".loc", MCAsmParser::DirectiveHandler(
163                                  &GenericAsmParser::ParseDirectiveLoc));
164   }
165
166   bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); // ".file"
167   bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); // ".line"
168   bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); // ".loc"
169 };
170
171 }
172
173 namespace llvm {
174
175 extern MCAsmParserExtension *createDarwinAsmParser();
176 extern MCAsmParserExtension *createELFAsmParser();
177
178 }
179
180 enum { DEFAULT_ADDRSPACE = 0 };
181
182 AsmParser::AsmParser(const Target &T, SourceMgr &_SM, MCContext &_Ctx,
183                      MCStreamer &_Out, const MCAsmInfo &_MAI)
184   : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM),
185     GenericParser(new GenericAsmParser), PlatformParser(0),
186     CurBuffer(0) {
187   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
188
189   // Initialize the generic parser.
190   GenericParser->Initialize(*this);
191
192   // Initialize the platform / file format parser.
193   //
194   // FIXME: This is a hack, we need to (majorly) cleanup how these objects are
195   // created.
196   if (_MAI.hasSubsectionsViaSymbols()) {
197     PlatformParser = createDarwinAsmParser();
198     PlatformParser->Initialize(*this);
199   } else {
200     PlatformParser = createELFAsmParser();
201     PlatformParser->Initialize(*this);
202   }
203 }
204
205 AsmParser::~AsmParser() {
206   delete PlatformParser;
207   delete GenericParser;
208 }
209
210 void AsmParser::Warning(SMLoc L, const Twine &Msg) {
211   PrintMessage(L, Msg.str(), "warning");
212 }
213
214 bool AsmParser::Error(SMLoc L, const Twine &Msg) {
215   PrintMessage(L, Msg.str(), "error");
216   return true;
217 }
218
219 void AsmParser::PrintMessage(SMLoc Loc, const std::string &Msg, 
220                              const char *Type) const {
221   SrcMgr.PrintMessage(Loc, Msg, Type);
222 }
223                   
224 bool AsmParser::EnterIncludeFile(const std::string &Filename) {
225   int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc());
226   if (NewBuf == -1)
227     return true;
228   
229   CurBuffer = NewBuf;
230   
231   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
232   
233   return false;
234 }
235                   
236 const AsmToken &AsmParser::Lex() {
237   const AsmToken *tok = &Lexer.Lex();
238   
239   if (tok->is(AsmToken::Eof)) {
240     // If this is the end of an included file, pop the parent file off the
241     // include stack.
242     SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
243     if (ParentIncludeLoc != SMLoc()) {
244       CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
245       Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), 
246                       ParentIncludeLoc.getPointer());
247       tok = &Lexer.Lex();
248     }
249   }
250     
251   if (tok->is(AsmToken::Error))
252     Error(Lexer.getErrLoc(), Lexer.getErr());
253   
254   return *tok;
255 }
256
257 bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
258   // Create the initial section, if requested.
259   //
260   // FIXME: Target hook & command line option for initial section.
261   if (!NoInitialTextSection)
262     Out.SwitchSection(Ctx.getMachOSection("__TEXT", "__text",
263                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
264                                       0, SectionKind::getText()));
265
266   // Prime the lexer.
267   Lex();
268   
269   bool HadError = false;
270   
271   AsmCond StartingCondState = TheCondState;
272
273   // While we have input, parse each statement.
274   while (Lexer.isNot(AsmToken::Eof)) {
275     if (!ParseStatement()) continue;
276   
277     // We had an error, remember it and recover by skipping to the next line.
278     HadError = true;
279     EatToEndOfStatement();
280   }
281
282   if (TheCondState.TheCond != StartingCondState.TheCond ||
283       TheCondState.Ignore != StartingCondState.Ignore)
284     return TokError("unmatched .ifs or .elses");
285   
286   // Finalize the output stream if there are no errors and if the client wants
287   // us to.
288   if (!HadError && !NoFinalize)  
289     Out.Finish();
290
291   return HadError;
292 }
293
294 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
295 void AsmParser::EatToEndOfStatement() {
296   while (Lexer.isNot(AsmToken::EndOfStatement) &&
297          Lexer.isNot(AsmToken::Eof))
298     Lex();
299   
300   // Eat EOL.
301   if (Lexer.is(AsmToken::EndOfStatement))
302     Lex();
303 }
304
305
306 /// ParseParenExpr - Parse a paren expression and return it.
307 /// NOTE: This assumes the leading '(' has already been consumed.
308 ///
309 /// parenexpr ::= expr)
310 ///
311 bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
312   if (ParseExpression(Res)) return true;
313   if (Lexer.isNot(AsmToken::RParen))
314     return TokError("expected ')' in parentheses expression");
315   EndLoc = Lexer.getLoc();
316   Lex();
317   return false;
318 }
319
320 /// ParsePrimaryExpr - Parse a primary expression and return it.
321 ///  primaryexpr ::= (parenexpr
322 ///  primaryexpr ::= symbol
323 ///  primaryexpr ::= number
324 ///  primaryexpr ::= '.'
325 ///  primaryexpr ::= ~,+,- primaryexpr
326 bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
327   switch (Lexer.getKind()) {
328   default:
329     return TokError("unknown token in expression");
330   case AsmToken::Exclaim:
331     Lex(); // Eat the operator.
332     if (ParsePrimaryExpr(Res, EndLoc))
333       return true;
334     Res = MCUnaryExpr::CreateLNot(Res, getContext());
335     return false;
336   case AsmToken::String:
337   case AsmToken::Identifier: {
338     // This is a symbol reference.
339     std::pair<StringRef, StringRef> Split = getTok().getIdentifier().split('@');
340     MCSymbol *Sym = getContext().GetOrCreateSymbol(Split.first);
341
342     // Mark the symbol as used in an expression.
343     Sym->setUsedInExpr(true);
344
345     // Lookup the symbol variant if used.
346     MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
347     if (Split.first.size() != getTok().getIdentifier().size())
348       Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
349
350     EndLoc = Lexer.getLoc();
351     Lex(); // Eat identifier.
352
353     // If this is an absolute variable reference, substitute it now to preserve
354     // semantics in the face of reassignment.
355     if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) {
356       if (Variant)
357         return Error(EndLoc, "unexpected modified on variable reference");
358
359       Res = Sym->getVariableValue();
360       return false;
361     }
362
363     // Otherwise create a symbol ref.
364     Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
365     return false;
366   }
367   case AsmToken::Integer: {
368     SMLoc Loc = getTok().getLoc();
369     int64_t IntVal = getTok().getIntVal();
370     Res = MCConstantExpr::Create(IntVal, getContext());
371     EndLoc = Lexer.getLoc();
372     Lex(); // Eat token.
373     // Look for 'b' or 'f' following an Integer as a directional label
374     if (Lexer.getKind() == AsmToken::Identifier) {
375       StringRef IDVal = getTok().getString();
376       if (IDVal == "f" || IDVal == "b"){
377         MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal,
378                                                       IDVal == "f" ? 1 : 0);
379         Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
380                                       getContext());
381         if(IDVal == "b" && Sym->isUndefined())
382           return Error(Loc, "invalid reference to undefined symbol");
383         EndLoc = Lexer.getLoc();
384         Lex(); // Eat identifier.
385       }
386     }
387     return false;
388   }
389   case AsmToken::Dot: {
390     // This is a '.' reference, which references the current PC.  Emit a
391     // temporary label to the streamer and refer to it.
392     MCSymbol *Sym = Ctx.CreateTempSymbol();
393     Out.EmitLabel(Sym);
394     Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
395     EndLoc = Lexer.getLoc();
396     Lex(); // Eat identifier.
397     return false;
398   }
399       
400   case AsmToken::LParen:
401     Lex(); // Eat the '('.
402     return ParseParenExpr(Res, EndLoc);
403   case AsmToken::Minus:
404     Lex(); // Eat the operator.
405     if (ParsePrimaryExpr(Res, EndLoc))
406       return true;
407     Res = MCUnaryExpr::CreateMinus(Res, getContext());
408     return false;
409   case AsmToken::Plus:
410     Lex(); // Eat the operator.
411     if (ParsePrimaryExpr(Res, EndLoc))
412       return true;
413     Res = MCUnaryExpr::CreatePlus(Res, getContext());
414     return false;
415   case AsmToken::Tilde:
416     Lex(); // Eat the operator.
417     if (ParsePrimaryExpr(Res, EndLoc))
418       return true;
419     Res = MCUnaryExpr::CreateNot(Res, getContext());
420     return false;
421   }
422 }
423
424 bool AsmParser::ParseExpression(const MCExpr *&Res) {
425   SMLoc EndLoc;
426   return ParseExpression(Res, EndLoc);
427 }
428
429 /// ParseExpression - Parse an expression and return it.
430 /// 
431 ///  expr ::= expr +,- expr          -> lowest.
432 ///  expr ::= expr |,^,&,! expr      -> middle.
433 ///  expr ::= expr *,/,%,<<,>> expr  -> highest.
434 ///  expr ::= primaryexpr
435 ///
436 bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
437   // Parse the expression.
438   Res = 0;
439   if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
440     return true;
441
442   // Try to constant fold it up front, if possible.
443   int64_t Value;
444   if (Res->EvaluateAsAbsolute(Value))
445     Res = MCConstantExpr::Create(Value, getContext());
446
447   return false;
448 }
449
450 bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
451   Res = 0;
452   return ParseParenExpr(Res, EndLoc) ||
453          ParseBinOpRHS(1, Res, EndLoc);
454 }
455
456 bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
457   const MCExpr *Expr;
458   
459   SMLoc StartLoc = Lexer.getLoc();
460   if (ParseExpression(Expr))
461     return true;
462
463   if (!Expr->EvaluateAsAbsolute(Res))
464     return Error(StartLoc, "expected absolute expression");
465
466   return false;
467 }
468
469 static unsigned getBinOpPrecedence(AsmToken::TokenKind K, 
470                                    MCBinaryExpr::Opcode &Kind) {
471   switch (K) {
472   default:
473     return 0;    // not a binop.
474
475     // Lowest Precedence: &&, ||
476   case AsmToken::AmpAmp:
477     Kind = MCBinaryExpr::LAnd;
478     return 1;
479   case AsmToken::PipePipe:
480     Kind = MCBinaryExpr::LOr;
481     return 1;
482
483     // Low Precedence: +, -, ==, !=, <>, <, <=, >, >=
484   case AsmToken::Plus:
485     Kind = MCBinaryExpr::Add;
486     return 2;
487   case AsmToken::Minus:
488     Kind = MCBinaryExpr::Sub;
489     return 2;
490   case AsmToken::EqualEqual:
491     Kind = MCBinaryExpr::EQ;
492     return 2;
493   case AsmToken::ExclaimEqual:
494   case AsmToken::LessGreater:
495     Kind = MCBinaryExpr::NE;
496     return 2;
497   case AsmToken::Less:
498     Kind = MCBinaryExpr::LT;
499     return 2;
500   case AsmToken::LessEqual:
501     Kind = MCBinaryExpr::LTE;
502     return 2;
503   case AsmToken::Greater:
504     Kind = MCBinaryExpr::GT;
505     return 2;
506   case AsmToken::GreaterEqual:
507     Kind = MCBinaryExpr::GTE;
508     return 2;
509
510     // Intermediate Precedence: |, &, ^
511     //
512     // FIXME: gas seems to support '!' as an infix operator?
513   case AsmToken::Pipe:
514     Kind = MCBinaryExpr::Or;
515     return 3;
516   case AsmToken::Caret:
517     Kind = MCBinaryExpr::Xor;
518     return 3;
519   case AsmToken::Amp:
520     Kind = MCBinaryExpr::And;
521     return 3;
522
523     // Highest Precedence: *, /, %, <<, >>
524   case AsmToken::Star:
525     Kind = MCBinaryExpr::Mul;
526     return 4;
527   case AsmToken::Slash:
528     Kind = MCBinaryExpr::Div;
529     return 4;
530   case AsmToken::Percent:
531     Kind = MCBinaryExpr::Mod;
532     return 4;
533   case AsmToken::LessLess:
534     Kind = MCBinaryExpr::Shl;
535     return 4;
536   case AsmToken::GreaterGreater:
537     Kind = MCBinaryExpr::Shr;
538     return 4;
539   }
540 }
541
542
543 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
544 /// Res contains the LHS of the expression on input.
545 bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
546                               SMLoc &EndLoc) {
547   while (1) {
548     MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
549     unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
550     
551     // If the next token is lower precedence than we are allowed to eat, return
552     // successfully with what we ate already.
553     if (TokPrec < Precedence)
554       return false;
555     
556     Lex();
557     
558     // Eat the next primary expression.
559     const MCExpr *RHS;
560     if (ParsePrimaryExpr(RHS, EndLoc)) return true;
561     
562     // If BinOp binds less tightly with RHS than the operator after RHS, let
563     // the pending operator take RHS as its LHS.
564     MCBinaryExpr::Opcode Dummy;
565     unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
566     if (TokPrec < NextTokPrec) {
567       if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
568     }
569
570     // Merge LHS and RHS according to operator.
571     Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
572   }
573 }
574
575   
576   
577   
578 /// ParseStatement:
579 ///   ::= EndOfStatement
580 ///   ::= Label* Directive ...Operands... EndOfStatement
581 ///   ::= Label* Identifier OperandList* EndOfStatement
582 bool AsmParser::ParseStatement() {
583   if (Lexer.is(AsmToken::EndOfStatement)) {
584     Out.AddBlankLine();
585     Lex();
586     return false;
587   }
588
589   // Statements always start with an identifier.
590   AsmToken ID = getTok();
591   SMLoc IDLoc = ID.getLoc();
592   StringRef IDVal;
593   int64_t LocalLabelVal = -1;
594   // GUESS allow an integer followed by a ':' as a directional local label
595   if (Lexer.is(AsmToken::Integer)) {
596     LocalLabelVal = getTok().getIntVal();
597     if (LocalLabelVal < 0) {
598       if (!TheCondState.Ignore)
599         return TokError("unexpected token at start of statement");
600       IDVal = "";
601     }
602     else {
603       IDVal = getTok().getString();
604       Lex(); // Consume the integer token to be used as an identifier token.
605       if (Lexer.getKind() != AsmToken::Colon) {
606         if (!TheCondState.Ignore)
607           return TokError("unexpected token at start of statement");
608       }
609     }
610   }
611   else if (ParseIdentifier(IDVal)) {
612     if (!TheCondState.Ignore)
613       return TokError("unexpected token at start of statement");
614     IDVal = "";
615   }
616
617   // Handle conditional assembly here before checking for skipping.  We
618   // have to do this so that .endif isn't skipped in a ".if 0" block for
619   // example.
620   if (IDVal == ".if")
621     return ParseDirectiveIf(IDLoc);
622   if (IDVal == ".elseif")
623     return ParseDirectiveElseIf(IDLoc);
624   if (IDVal == ".else")
625     return ParseDirectiveElse(IDLoc);
626   if (IDVal == ".endif")
627     return ParseDirectiveEndIf(IDLoc);
628     
629   // If we are in a ".if 0" block, ignore this statement.
630   if (TheCondState.Ignore) {
631     EatToEndOfStatement();
632     return false;
633   }
634   
635   // FIXME: Recurse on local labels?
636
637   // See what kind of statement we have.
638   switch (Lexer.getKind()) {
639   case AsmToken::Colon: {
640     // identifier ':'   -> Label.
641     Lex();
642
643     // Diagnose attempt to use a variable as a label.
644     //
645     // FIXME: Diagnostics. Note the location of the definition as a label.
646     // FIXME: This doesn't diagnose assignment to a symbol which has been
647     // implicitly marked as external.
648     MCSymbol *Sym;
649     if (LocalLabelVal == -1)
650       Sym = getContext().GetOrCreateSymbol(IDVal);
651     else
652       Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
653     if (!Sym->isUndefined() || Sym->isVariable())
654       return Error(IDLoc, "invalid symbol redefinition");
655     
656     // Emit the label.
657     Out.EmitLabel(Sym);
658    
659     // Consume any end of statement token, if present, to avoid spurious
660     // AddBlankLine calls().
661     if (Lexer.is(AsmToken::EndOfStatement)) {
662       Lex();
663       if (Lexer.is(AsmToken::Eof))
664         return false;
665     }
666
667     return ParseStatement();
668   }
669
670   case AsmToken::Equal:
671     // identifier '=' ... -> assignment statement
672     Lex();
673
674     return ParseAssignment(IDVal);
675
676   default: // Normal instruction or directive.
677     break;
678   }
679   
680   // Otherwise, we have a normal instruction or directive.  
681   if (IDVal[0] == '.') {
682     // Assembler features
683     if (IDVal == ".set")
684       return ParseDirectiveSet();
685
686     // Data directives
687
688     if (IDVal == ".ascii")
689       return ParseDirectiveAscii(false);
690     if (IDVal == ".asciz")
691       return ParseDirectiveAscii(true);
692
693     if (IDVal == ".byte")
694       return ParseDirectiveValue(1);
695     if (IDVal == ".short")
696       return ParseDirectiveValue(2);
697     if (IDVal == ".long")
698       return ParseDirectiveValue(4);
699     if (IDVal == ".quad")
700       return ParseDirectiveValue(8);
701
702     // FIXME: Target hooks for IsPow2.
703     if (IDVal == ".align")
704       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
705     if (IDVal == ".align32")
706       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
707     if (IDVal == ".balign")
708       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
709     if (IDVal == ".balignw")
710       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
711     if (IDVal == ".balignl")
712       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
713     if (IDVal == ".p2align")
714       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
715     if (IDVal == ".p2alignw")
716       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
717     if (IDVal == ".p2alignl")
718       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
719
720     if (IDVal == ".org")
721       return ParseDirectiveOrg();
722
723     if (IDVal == ".fill")
724       return ParseDirectiveFill();
725     if (IDVal == ".space")
726       return ParseDirectiveSpace();
727
728     // Symbol attribute directives
729
730     if (IDVal == ".globl" || IDVal == ".global")
731       return ParseDirectiveSymbolAttribute(MCSA_Global);
732     if (IDVal == ".hidden")
733       return ParseDirectiveSymbolAttribute(MCSA_Hidden);
734     if (IDVal == ".indirect_symbol")
735       return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
736     if (IDVal == ".internal")
737       return ParseDirectiveSymbolAttribute(MCSA_Internal);
738     if (IDVal == ".lazy_reference")
739       return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
740     if (IDVal == ".no_dead_strip")
741       return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
742     if (IDVal == ".private_extern")
743       return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
744     if (IDVal == ".protected")
745       return ParseDirectiveSymbolAttribute(MCSA_Protected);
746     if (IDVal == ".reference")
747       return ParseDirectiveSymbolAttribute(MCSA_Reference);
748     if (IDVal == ".type")
749       return ParseDirectiveELFType();
750     if (IDVal == ".weak")
751       return ParseDirectiveSymbolAttribute(MCSA_Weak);
752     if (IDVal == ".weak_definition")
753       return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition);
754     if (IDVal == ".weak_reference")
755       return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
756     if (IDVal == ".weak_def_can_be_hidden")
757       return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
758
759     if (IDVal == ".comm")
760       return ParseDirectiveComm(/*IsLocal=*/false);
761     if (IDVal == ".lcomm")
762       return ParseDirectiveComm(/*IsLocal=*/true);
763
764     if (IDVal == ".abort")
765       return ParseDirectiveAbort();
766     if (IDVal == ".include")
767       return ParseDirectiveInclude();
768
769     // Look up the handler in the handler table.
770     std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
771       DirectiveMap.lookup(IDVal);
772     if (Handler.first)
773       return (Handler.first->*Handler.second)(IDVal, IDLoc);
774
775     // Target hook for parsing target specific directives.
776     if (!getTargetParser().ParseDirective(ID))
777       return false;
778
779     Warning(IDLoc, "ignoring directive for now");
780     EatToEndOfStatement();
781     return false;
782   }
783
784   // Canonicalize the opcode to lower case.
785   SmallString<128> Opcode;
786   for (unsigned i = 0, e = IDVal.size(); i != e; ++i)
787     Opcode.push_back(tolower(IDVal[i]));
788   
789   SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
790   bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc,
791                                                      ParsedOperands);
792   if (!HadError && Lexer.isNot(AsmToken::EndOfStatement))
793     HadError = TokError("unexpected token in argument list");
794
795   // If parsing succeeded, match the instruction.
796   if (!HadError) {
797     MCInst Inst;
798     if (!getTargetParser().MatchInstruction(ParsedOperands, Inst)) {
799       // Emit the instruction on success.
800       Out.EmitInstruction(Inst);
801     } else {
802       // Otherwise emit a diagnostic about the match failure and set the error
803       // flag.
804       //
805       // FIXME: We should give nicer diagnostics about the exact failure.
806       Error(IDLoc, "unrecognized instruction");
807       HadError = true;
808     }
809   }
810
811   // If there was no error, consume the end-of-statement token. Otherwise this
812   // will be done by our caller.
813   if (!HadError)
814     Lex();
815
816   // Free any parsed operands.
817   for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
818     delete ParsedOperands[i];
819
820   return HadError;
821 }
822
823 bool AsmParser::ParseAssignment(StringRef Name) {
824   // FIXME: Use better location, we should use proper tokens.
825   SMLoc EqualLoc = Lexer.getLoc();
826
827   const MCExpr *Value;
828   if (ParseExpression(Value))
829     return true;
830   
831   if (Lexer.isNot(AsmToken::EndOfStatement))
832     return TokError("unexpected token in assignment");
833
834   // Eat the end of statement marker.
835   Lex();
836
837   // Validate that the LHS is allowed to be a variable (either it has not been
838   // used as a symbol, or it is an absolute symbol).
839   MCSymbol *Sym = getContext().LookupSymbol(Name);
840   if (Sym) {
841     // Diagnose assignment to a label.
842     //
843     // FIXME: Diagnostics. Note the location of the definition as a label.
844     // FIXME: Diagnose assignment to protected identifier (e.g., register name).
845     if (Sym->isUndefined() && !Sym->isUsedInExpr())
846       ; // Allow redefinitions of undefined symbols only used in directives.
847     else if (!Sym->isUndefined() && !Sym->isAbsolute())
848       return Error(EqualLoc, "redefinition of '" + Name + "'");
849     else if (!Sym->isVariable())
850       return Error(EqualLoc, "invalid assignment to '" + Name + "'");
851     else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
852       return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
853                    Name + "'");
854   } else
855     Sym = getContext().GetOrCreateSymbol(Name);
856
857   // FIXME: Handle '.'.
858
859   Sym->setUsedInExpr(true);
860
861   // Do the assignment.
862   Out.EmitAssignment(Sym, Value);
863
864   return false;
865 }
866
867 /// ParseIdentifier:
868 ///   ::= identifier
869 ///   ::= string
870 bool AsmParser::ParseIdentifier(StringRef &Res) {
871   if (Lexer.isNot(AsmToken::Identifier) &&
872       Lexer.isNot(AsmToken::String))
873     return true;
874
875   Res = getTok().getIdentifier();
876
877   Lex(); // Consume the identifier token.
878
879   return false;
880 }
881
882 /// ParseDirectiveSet:
883 ///   ::= .set identifier ',' expression
884 bool AsmParser::ParseDirectiveSet() {
885   StringRef Name;
886
887   if (ParseIdentifier(Name))
888     return TokError("expected identifier after '.set' directive");
889   
890   if (getLexer().isNot(AsmToken::Comma))
891     return TokError("unexpected token in '.set'");
892   Lex();
893
894   return ParseAssignment(Name);
895 }
896
897 bool AsmParser::ParseEscapedString(std::string &Data) {
898   assert(getLexer().is(AsmToken::String) && "Unexpected current token!");
899
900   Data = "";
901   StringRef Str = getTok().getStringContents();
902   for (unsigned i = 0, e = Str.size(); i != e; ++i) {
903     if (Str[i] != '\\') {
904       Data += Str[i];
905       continue;
906     }
907
908     // Recognize escaped characters. Note that this escape semantics currently
909     // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
910     ++i;
911     if (i == e)
912       return TokError("unexpected backslash at end of string");
913
914     // Recognize octal sequences.
915     if ((unsigned) (Str[i] - '0') <= 7) {
916       // Consume up to three octal characters.
917       unsigned Value = Str[i] - '0';
918
919       if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
920         ++i;
921         Value = Value * 8 + (Str[i] - '0');
922
923         if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
924           ++i;
925           Value = Value * 8 + (Str[i] - '0');
926         }
927       }
928
929       if (Value > 255)
930         return TokError("invalid octal escape sequence (out of range)");
931
932       Data += (unsigned char) Value;
933       continue;
934     }
935
936     // Otherwise recognize individual escapes.
937     switch (Str[i]) {
938     default:
939       // Just reject invalid escape sequences for now.
940       return TokError("invalid escape sequence (unrecognized character)");
941
942     case 'b': Data += '\b'; break;
943     case 'f': Data += '\f'; break;
944     case 'n': Data += '\n'; break;
945     case 'r': Data += '\r'; break;
946     case 't': Data += '\t'; break;
947     case '"': Data += '"'; break;
948     case '\\': Data += '\\'; break;
949     }
950   }
951
952   return false;
953 }
954
955 /// ParseDirectiveAscii:
956 ///   ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ]
957 bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
958   if (getLexer().isNot(AsmToken::EndOfStatement)) {
959     for (;;) {
960       if (getLexer().isNot(AsmToken::String))
961         return TokError("expected string in '.ascii' or '.asciz' directive");
962
963       std::string Data;
964       if (ParseEscapedString(Data))
965         return true;
966
967       getStreamer().EmitBytes(Data, DEFAULT_ADDRSPACE);
968       if (ZeroTerminated)
969         getStreamer().EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
970
971       Lex();
972
973       if (getLexer().is(AsmToken::EndOfStatement))
974         break;
975
976       if (getLexer().isNot(AsmToken::Comma))
977         return TokError("unexpected token in '.ascii' or '.asciz' directive");
978       Lex();
979     }
980   }
981
982   Lex();
983   return false;
984 }
985
986 /// ParseDirectiveValue
987 ///  ::= (.byte | .short | ... ) [ expression (, expression)* ]
988 bool AsmParser::ParseDirectiveValue(unsigned Size) {
989   if (getLexer().isNot(AsmToken::EndOfStatement)) {
990     for (;;) {
991       const MCExpr *Value;
992       SMLoc ATTRIBUTE_UNUSED StartLoc = getLexer().getLoc();
993       if (ParseExpression(Value))
994         return true;
995
996       // Special case constant expressions to match code generator.
997       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value))
998         getStreamer().EmitIntValue(MCE->getValue(), Size, DEFAULT_ADDRSPACE);
999       else
1000         getStreamer().EmitValue(Value, Size, DEFAULT_ADDRSPACE);
1001
1002       if (getLexer().is(AsmToken::EndOfStatement))
1003         break;
1004       
1005       // FIXME: Improve diagnostic.
1006       if (getLexer().isNot(AsmToken::Comma))
1007         return TokError("unexpected token in directive");
1008       Lex();
1009     }
1010   }
1011
1012   Lex();
1013   return false;
1014 }
1015
1016 /// ParseDirectiveSpace
1017 ///  ::= .space expression [ , expression ]
1018 bool AsmParser::ParseDirectiveSpace() {
1019   int64_t NumBytes;
1020   if (ParseAbsoluteExpression(NumBytes))
1021     return true;
1022
1023   int64_t FillExpr = 0;
1024   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1025     if (getLexer().isNot(AsmToken::Comma))
1026       return TokError("unexpected token in '.space' directive");
1027     Lex();
1028     
1029     if (ParseAbsoluteExpression(FillExpr))
1030       return true;
1031
1032     if (getLexer().isNot(AsmToken::EndOfStatement))
1033       return TokError("unexpected token in '.space' directive");
1034   }
1035
1036   Lex();
1037
1038   if (NumBytes <= 0)
1039     return TokError("invalid number of bytes in '.space' directive");
1040
1041   // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
1042   getStreamer().EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
1043
1044   return false;
1045 }
1046
1047 /// ParseDirectiveFill
1048 ///  ::= .fill expression , expression , expression
1049 bool AsmParser::ParseDirectiveFill() {
1050   int64_t NumValues;
1051   if (ParseAbsoluteExpression(NumValues))
1052     return true;
1053
1054   if (getLexer().isNot(AsmToken::Comma))
1055     return TokError("unexpected token in '.fill' directive");
1056   Lex();
1057   
1058   int64_t FillSize;
1059   if (ParseAbsoluteExpression(FillSize))
1060     return true;
1061
1062   if (getLexer().isNot(AsmToken::Comma))
1063     return TokError("unexpected token in '.fill' directive");
1064   Lex();
1065   
1066   int64_t FillExpr;
1067   if (ParseAbsoluteExpression(FillExpr))
1068     return true;
1069
1070   if (getLexer().isNot(AsmToken::EndOfStatement))
1071     return TokError("unexpected token in '.fill' directive");
1072   
1073   Lex();
1074
1075   if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
1076     return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
1077
1078   for (uint64_t i = 0, e = NumValues; i != e; ++i)
1079     getStreamer().EmitIntValue(FillExpr, FillSize, DEFAULT_ADDRSPACE);
1080
1081   return false;
1082 }
1083
1084 /// ParseDirectiveOrg
1085 ///  ::= .org expression [ , expression ]
1086 bool AsmParser::ParseDirectiveOrg() {
1087   const MCExpr *Offset;
1088   if (ParseExpression(Offset))
1089     return true;
1090
1091   // Parse optional fill expression.
1092   int64_t FillExpr = 0;
1093   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1094     if (getLexer().isNot(AsmToken::Comma))
1095       return TokError("unexpected token in '.org' directive");
1096     Lex();
1097     
1098     if (ParseAbsoluteExpression(FillExpr))
1099       return true;
1100
1101     if (getLexer().isNot(AsmToken::EndOfStatement))
1102       return TokError("unexpected token in '.org' directive");
1103   }
1104
1105   Lex();
1106
1107   // FIXME: Only limited forms of relocatable expressions are accepted here, it
1108   // has to be relative to the current section.
1109   getStreamer().EmitValueToOffset(Offset, FillExpr);
1110
1111   return false;
1112 }
1113
1114 /// ParseDirectiveAlign
1115 ///  ::= {.align, ...} expression [ , expression [ , expression ]]
1116 bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
1117   SMLoc AlignmentLoc = getLexer().getLoc();
1118   int64_t Alignment;
1119   if (ParseAbsoluteExpression(Alignment))
1120     return true;
1121
1122   SMLoc MaxBytesLoc;
1123   bool HasFillExpr = false;
1124   int64_t FillExpr = 0;
1125   int64_t MaxBytesToFill = 0;
1126   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1127     if (getLexer().isNot(AsmToken::Comma))
1128       return TokError("unexpected token in directive");
1129     Lex();
1130
1131     // The fill expression can be omitted while specifying a maximum number of
1132     // alignment bytes, e.g:
1133     //  .align 3,,4
1134     if (getLexer().isNot(AsmToken::Comma)) {
1135       HasFillExpr = true;
1136       if (ParseAbsoluteExpression(FillExpr))
1137         return true;
1138     }
1139
1140     if (getLexer().isNot(AsmToken::EndOfStatement)) {
1141       if (getLexer().isNot(AsmToken::Comma))
1142         return TokError("unexpected token in directive");
1143       Lex();
1144
1145       MaxBytesLoc = getLexer().getLoc();
1146       if (ParseAbsoluteExpression(MaxBytesToFill))
1147         return true;
1148       
1149       if (getLexer().isNot(AsmToken::EndOfStatement))
1150         return TokError("unexpected token in directive");
1151     }
1152   }
1153
1154   Lex();
1155
1156   if (!HasFillExpr)
1157     FillExpr = 0;
1158
1159   // Compute alignment in bytes.
1160   if (IsPow2) {
1161     // FIXME: Diagnose overflow.
1162     if (Alignment >= 32) {
1163       Error(AlignmentLoc, "invalid alignment value");
1164       Alignment = 31;
1165     }
1166
1167     Alignment = 1ULL << Alignment;
1168   }
1169
1170   // Diagnose non-sensical max bytes to align.
1171   if (MaxBytesLoc.isValid()) {
1172     if (MaxBytesToFill < 1) {
1173       Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
1174             "many bytes, ignoring maximum bytes expression");
1175       MaxBytesToFill = 0;
1176     }
1177
1178     if (MaxBytesToFill >= Alignment) {
1179       Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
1180               "has no effect");
1181       MaxBytesToFill = 0;
1182     }
1183   }
1184
1185   // Check whether we should use optimal code alignment for this .align
1186   // directive.
1187   //
1188   // FIXME: This should be using a target hook.
1189   bool UseCodeAlign = false;
1190   if (const MCSectionMachO *S = dyn_cast<MCSectionMachO>(
1191         getStreamer().getCurrentSection()))
1192     UseCodeAlign = S->hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
1193   if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
1194       ValueSize == 1 && UseCodeAlign) {
1195     getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill);
1196   } else {
1197     // FIXME: Target specific behavior about how the "extra" bytes are filled.
1198     getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize,
1199                                        MaxBytesToFill);
1200   }
1201
1202   return false;
1203 }
1204
1205 /// ParseDirectiveSymbolAttribute
1206 ///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
1207 bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
1208   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1209     for (;;) {
1210       StringRef Name;
1211
1212       if (ParseIdentifier(Name))
1213         return TokError("expected identifier in directive");
1214       
1215       MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
1216
1217       getStreamer().EmitSymbolAttribute(Sym, Attr);
1218
1219       if (getLexer().is(AsmToken::EndOfStatement))
1220         break;
1221
1222       if (getLexer().isNot(AsmToken::Comma))
1223         return TokError("unexpected token in directive");
1224       Lex();
1225     }
1226   }
1227
1228   Lex();
1229   return false;  
1230 }
1231
1232 /// ParseDirectiveELFType
1233 ///  ::= .type identifier , @attribute
1234 bool AsmParser::ParseDirectiveELFType() {
1235   StringRef Name;
1236   if (ParseIdentifier(Name))
1237     return TokError("expected identifier in directive");
1238
1239   // Handle the identifier as the key symbol.
1240   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
1241
1242   if (getLexer().isNot(AsmToken::Comma))
1243     return TokError("unexpected token in '.type' directive");
1244   Lex();
1245
1246   if (getLexer().isNot(AsmToken::At))
1247     return TokError("expected '@' before type");
1248   Lex();
1249
1250   StringRef Type;
1251   SMLoc TypeLoc;
1252
1253   TypeLoc = getLexer().getLoc();
1254   if (ParseIdentifier(Type))
1255     return TokError("expected symbol type in directive");
1256
1257   MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type)
1258     .Case("function", MCSA_ELF_TypeFunction)
1259     .Case("object", MCSA_ELF_TypeObject)
1260     .Case("tls_object", MCSA_ELF_TypeTLS)
1261     .Case("common", MCSA_ELF_TypeCommon)
1262     .Case("notype", MCSA_ELF_TypeNoType)
1263     .Default(MCSA_Invalid);
1264
1265   if (Attr == MCSA_Invalid)
1266     return Error(TypeLoc, "unsupported attribute in '.type' directive");
1267
1268   if (getLexer().isNot(AsmToken::EndOfStatement))
1269     return TokError("unexpected token in '.type' directive");
1270
1271   Lex();
1272
1273   getStreamer().EmitSymbolAttribute(Sym, Attr);
1274
1275   return false;
1276 }
1277
1278 /// ParseDirectiveComm
1279 ///  ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
1280 bool AsmParser::ParseDirectiveComm(bool IsLocal) {
1281   SMLoc IDLoc = getLexer().getLoc();
1282   StringRef Name;
1283   if (ParseIdentifier(Name))
1284     return TokError("expected identifier in directive");
1285   
1286   // Handle the identifier as the key symbol.
1287   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
1288
1289   if (getLexer().isNot(AsmToken::Comma))
1290     return TokError("unexpected token in directive");
1291   Lex();
1292
1293   int64_t Size;
1294   SMLoc SizeLoc = getLexer().getLoc();
1295   if (ParseAbsoluteExpression(Size))
1296     return true;
1297
1298   int64_t Pow2Alignment = 0;
1299   SMLoc Pow2AlignmentLoc;
1300   if (getLexer().is(AsmToken::Comma)) {
1301     Lex();
1302     Pow2AlignmentLoc = getLexer().getLoc();
1303     if (ParseAbsoluteExpression(Pow2Alignment))
1304       return true;
1305     
1306     // If this target takes alignments in bytes (not log) validate and convert.
1307     if (Lexer.getMAI().getAlignmentIsInBytes()) {
1308       if (!isPowerOf2_64(Pow2Alignment))
1309         return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
1310       Pow2Alignment = Log2_64(Pow2Alignment);
1311     }
1312   }
1313   
1314   if (getLexer().isNot(AsmToken::EndOfStatement))
1315     return TokError("unexpected token in '.comm' or '.lcomm' directive");
1316   
1317   Lex();
1318
1319   // NOTE: a size of zero for a .comm should create a undefined symbol
1320   // but a size of .lcomm creates a bss symbol of size zero.
1321   if (Size < 0)
1322     return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
1323                  "be less than zero");
1324
1325   // NOTE: The alignment in the directive is a power of 2 value, the assembler
1326   // may internally end up wanting an alignment in bytes.
1327   // FIXME: Diagnose overflow.
1328   if (Pow2Alignment < 0)
1329     return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
1330                  "alignment, can't be less than zero");
1331
1332   if (!Sym->isUndefined())
1333     return Error(IDLoc, "invalid symbol redefinition");
1334
1335   // '.lcomm' is equivalent to '.zerofill'.
1336   // Create the Symbol as a common or local common with Size and Pow2Alignment
1337   if (IsLocal) {
1338     getStreamer().EmitZerofill(Ctx.getMachOSection(
1339                                  "__DATA", "__bss", MCSectionMachO::S_ZEROFILL,
1340                                  0, SectionKind::getBSS()),
1341                                Sym, Size, 1 << Pow2Alignment);
1342     return false;
1343   }
1344
1345   getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
1346   return false;
1347 }
1348
1349 /// ParseDirectiveAbort
1350 ///  ::= .abort [ "abort_string" ]
1351 bool AsmParser::ParseDirectiveAbort() {
1352   // FIXME: Use loc from directive.
1353   SMLoc Loc = getLexer().getLoc();
1354
1355   StringRef Str = "";
1356   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1357     if (getLexer().isNot(AsmToken::String))
1358       return TokError("expected string in '.abort' directive");
1359     
1360     Str = getTok().getString();
1361
1362     Lex();
1363   }
1364
1365   if (getLexer().isNot(AsmToken::EndOfStatement))
1366     return TokError("unexpected token in '.abort' directive");
1367   
1368   Lex();
1369
1370   // FIXME: Handle here.
1371   if (Str.empty())
1372     Error(Loc, ".abort detected. Assembly stopping.");
1373   else
1374     Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
1375
1376   return false;
1377 }
1378
1379 /// ParseDirectiveInclude
1380 ///  ::= .include "filename"
1381 bool AsmParser::ParseDirectiveInclude() {
1382   if (getLexer().isNot(AsmToken::String))
1383     return TokError("expected string in '.include' directive");
1384   
1385   std::string Filename = getTok().getString();
1386   SMLoc IncludeLoc = getLexer().getLoc();
1387   Lex();
1388
1389   if (getLexer().isNot(AsmToken::EndOfStatement))
1390     return TokError("unexpected token in '.include' directive");
1391   
1392   // Strip the quotes.
1393   Filename = Filename.substr(1, Filename.size()-2);
1394   
1395   // Attempt to switch the lexer to the included file before consuming the end
1396   // of statement to avoid losing it when we switch.
1397   if (EnterIncludeFile(Filename)) {
1398     Error(IncludeLoc, "Could not find include file '" + Filename + "'");
1399     return true;
1400   }
1401
1402   return false;
1403 }
1404
1405 /// ParseDirectiveIf
1406 /// ::= .if expression
1407 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
1408   TheCondStack.push_back(TheCondState);
1409   TheCondState.TheCond = AsmCond::IfCond;
1410   if(TheCondState.Ignore) {
1411     EatToEndOfStatement();
1412   }
1413   else {
1414     int64_t ExprValue;
1415     if (ParseAbsoluteExpression(ExprValue))
1416       return true;
1417
1418     if (getLexer().isNot(AsmToken::EndOfStatement))
1419       return TokError("unexpected token in '.if' directive");
1420     
1421     Lex();
1422
1423     TheCondState.CondMet = ExprValue;
1424     TheCondState.Ignore = !TheCondState.CondMet;
1425   }
1426
1427   return false;
1428 }
1429
1430 /// ParseDirectiveElseIf
1431 /// ::= .elseif expression
1432 bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
1433   if (TheCondState.TheCond != AsmCond::IfCond &&
1434       TheCondState.TheCond != AsmCond::ElseIfCond)
1435       Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
1436                           " an .elseif");
1437   TheCondState.TheCond = AsmCond::ElseIfCond;
1438
1439   bool LastIgnoreState = false;
1440   if (!TheCondStack.empty())
1441       LastIgnoreState = TheCondStack.back().Ignore;
1442   if (LastIgnoreState || TheCondState.CondMet) {
1443     TheCondState.Ignore = true;
1444     EatToEndOfStatement();
1445   }
1446   else {
1447     int64_t ExprValue;
1448     if (ParseAbsoluteExpression(ExprValue))
1449       return true;
1450
1451     if (getLexer().isNot(AsmToken::EndOfStatement))
1452       return TokError("unexpected token in '.elseif' directive");
1453     
1454     Lex();
1455     TheCondState.CondMet = ExprValue;
1456     TheCondState.Ignore = !TheCondState.CondMet;
1457   }
1458
1459   return false;
1460 }
1461
1462 /// ParseDirectiveElse
1463 /// ::= .else
1464 bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
1465   if (getLexer().isNot(AsmToken::EndOfStatement))
1466     return TokError("unexpected token in '.else' directive");
1467   
1468   Lex();
1469
1470   if (TheCondState.TheCond != AsmCond::IfCond &&
1471       TheCondState.TheCond != AsmCond::ElseIfCond)
1472       Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
1473                           ".elseif");
1474   TheCondState.TheCond = AsmCond::ElseCond;
1475   bool LastIgnoreState = false;
1476   if (!TheCondStack.empty())
1477     LastIgnoreState = TheCondStack.back().Ignore;
1478   if (LastIgnoreState || TheCondState.CondMet)
1479     TheCondState.Ignore = true;
1480   else
1481     TheCondState.Ignore = false;
1482
1483   return false;
1484 }
1485
1486 /// ParseDirectiveEndIf
1487 /// ::= .endif
1488 bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
1489   if (getLexer().isNot(AsmToken::EndOfStatement))
1490     return TokError("unexpected token in '.endif' directive");
1491   
1492   Lex();
1493
1494   if ((TheCondState.TheCond == AsmCond::NoCond) ||
1495       TheCondStack.empty())
1496     Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
1497                         ".else");
1498   if (!TheCondStack.empty()) {
1499     TheCondState = TheCondStack.back();
1500     TheCondStack.pop_back();
1501   }
1502
1503   return false;
1504 }
1505
1506 /// ParseDirectiveFile
1507 /// ::= .file [number] string
1508 bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
1509   // FIXME: I'm not sure what this is.
1510   int64_t FileNumber = -1;
1511   if (getLexer().is(AsmToken::Integer)) {
1512     FileNumber = getTok().getIntVal();
1513     Lex();
1514
1515     if (FileNumber < 1)
1516       return TokError("file number less than one");
1517   }
1518
1519   if (getLexer().isNot(AsmToken::String))
1520     return TokError("unexpected token in '.file' directive");
1521
1522   StringRef Filename = getTok().getString();
1523   Filename = Filename.substr(1, Filename.size()-2);
1524   Lex();
1525
1526   if (getLexer().isNot(AsmToken::EndOfStatement))
1527     return TokError("unexpected token in '.file' directive");
1528
1529   if (FileNumber == -1)
1530     getStreamer().EmitFileDirective(Filename);
1531   else
1532     getStreamer().EmitDwarfFileDirective(FileNumber, Filename);
1533
1534   return false;
1535 }
1536
1537 /// ParseDirectiveLine
1538 /// ::= .line [number]
1539 bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
1540   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1541     if (getLexer().isNot(AsmToken::Integer))
1542       return TokError("unexpected token in '.line' directive");
1543
1544     int64_t LineNumber = getTok().getIntVal();
1545     (void) LineNumber;
1546     Lex();
1547
1548     // FIXME: Do something with the .line.
1549   }
1550
1551   if (getLexer().isNot(AsmToken::EndOfStatement))
1552     return TokError("unexpected token in '.line' directive");
1553
1554   return false;
1555 }
1556
1557
1558 /// ParseDirectiveLoc
1559 /// ::= .loc number [number [number]]
1560 bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
1561   if (getLexer().isNot(AsmToken::Integer))
1562     return TokError("unexpected token in '.loc' directive");
1563
1564   // FIXME: What are these fields?
1565   int64_t FileNumber = getTok().getIntVal();
1566   (void) FileNumber;
1567   // FIXME: Validate file.
1568
1569   Lex();
1570   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1571     if (getLexer().isNot(AsmToken::Integer))
1572       return TokError("unexpected token in '.loc' directive");
1573
1574     int64_t Param2 = getTok().getIntVal();
1575     (void) Param2;
1576     Lex();
1577
1578     if (getLexer().isNot(AsmToken::EndOfStatement)) {
1579       if (getLexer().isNot(AsmToken::Integer))
1580         return TokError("unexpected token in '.loc' directive");
1581
1582       int64_t Param3 = getTok().getIntVal();
1583       (void) Param3;
1584       Lex();
1585
1586       // FIXME: Do something with the .loc.
1587     }
1588   }
1589
1590   if (getLexer().isNot(AsmToken::EndOfStatement))
1591     return TokError("unexpected token in '.file' directive");
1592
1593   return false;
1594 }
1595
1596
1597 /// \brief Create an MCAsmParser instance.
1598 MCAsmParser *llvm::createMCAsmParser(const Target &T, SourceMgr &SM,
1599                                      MCContext &C, MCStreamer &Out,
1600                                      const MCAsmInfo &MAI) {
1601   return new AsmParser(T, SM, C, Out, MAI);
1602 }