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