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