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