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