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