llvm-mc: Support reassignment of variables in one special case, when the
[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     // FIXME: Sometimes fill with nop.
1183     FillExpr = 0;
1184   }
1185
1186   // Compute alignment in bytes.
1187   if (IsPow2) {
1188     // FIXME: Diagnose overflow.
1189     if (Alignment >= 32) {
1190       Error(AlignmentLoc, "invalid alignment value");
1191       Alignment = 31;
1192     }
1193
1194     Alignment = 1ULL << Alignment;
1195   }
1196
1197   // Diagnose non-sensical max bytes to align.
1198   if (MaxBytesLoc.isValid()) {
1199     if (MaxBytesToFill < 1) {
1200       Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
1201             "many bytes, ignoring maximum bytes expression");
1202       MaxBytesToFill = 0;
1203     }
1204
1205     if (MaxBytesToFill >= Alignment) {
1206       Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
1207               "has no effect");
1208       MaxBytesToFill = 0;
1209     }
1210   }
1211
1212   // FIXME: hard code the parser to use EmitCodeAlignment for text when using
1213   // the TextAlignFillValue.
1214   if(Out.getCurrentSection()->getKind().isText() && 
1215      Lexer.getMAI().getTextAlignFillValue() == FillExpr)
1216     Out.EmitCodeAlignment(Alignment, MaxBytesToFill);
1217   else
1218     // FIXME: Target specific behavior about how the "extra" bytes are filled.
1219     Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
1220
1221   return false;
1222 }
1223
1224 /// ParseDirectiveSymbolAttribute
1225 ///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
1226 bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
1227   if (Lexer.isNot(AsmToken::EndOfStatement)) {
1228     for (;;) {
1229       StringRef Name;
1230
1231       if (ParseIdentifier(Name))
1232         return TokError("expected identifier in directive");
1233       
1234       MCSymbol *Sym = CreateSymbol(Name);
1235
1236       Out.EmitSymbolAttribute(Sym, Attr);
1237
1238       if (Lexer.is(AsmToken::EndOfStatement))
1239         break;
1240
1241       if (Lexer.isNot(AsmToken::Comma))
1242         return TokError("unexpected token in directive");
1243       Lex();
1244     }
1245   }
1246
1247   Lex();
1248   return false;  
1249 }
1250
1251 /// ParseDirectiveDarwinSymbolDesc
1252 ///  ::= .desc identifier , expression
1253 bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
1254   StringRef Name;
1255   if (ParseIdentifier(Name))
1256     return TokError("expected identifier in directive");
1257   
1258   // Handle the identifier as the key symbol.
1259   MCSymbol *Sym = CreateSymbol(Name);
1260
1261   if (Lexer.isNot(AsmToken::Comma))
1262     return TokError("unexpected token in '.desc' directive");
1263   Lex();
1264
1265   SMLoc DescLoc = Lexer.getLoc();
1266   int64_t DescValue;
1267   if (ParseAbsoluteExpression(DescValue))
1268     return true;
1269
1270   if (Lexer.isNot(AsmToken::EndOfStatement))
1271     return TokError("unexpected token in '.desc' directive");
1272   
1273   Lex();
1274
1275   // Set the n_desc field of this Symbol to this DescValue
1276   Out.EmitSymbolDesc(Sym, DescValue);
1277
1278   return false;
1279 }
1280
1281 /// ParseDirectiveComm
1282 ///  ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
1283 bool AsmParser::ParseDirectiveComm(bool IsLocal) {
1284   SMLoc IDLoc = Lexer.getLoc();
1285   StringRef Name;
1286   if (ParseIdentifier(Name))
1287     return TokError("expected identifier in directive");
1288   
1289   // Handle the identifier as the key symbol.
1290   MCSymbol *Sym = CreateSymbol(Name);
1291
1292   if (Lexer.isNot(AsmToken::Comma))
1293     return TokError("unexpected token in directive");
1294   Lex();
1295
1296   int64_t Size;
1297   SMLoc SizeLoc = Lexer.getLoc();
1298   if (ParseAbsoluteExpression(Size))
1299     return true;
1300
1301   int64_t Pow2Alignment = 0;
1302   SMLoc Pow2AlignmentLoc;
1303   if (Lexer.is(AsmToken::Comma)) {
1304     Lex();
1305     Pow2AlignmentLoc = Lexer.getLoc();
1306     if (ParseAbsoluteExpression(Pow2Alignment))
1307       return true;
1308     
1309     // If this target takes alignments in bytes (not log) validate and convert.
1310     if (Lexer.getMAI().getAlignmentIsInBytes()) {
1311       if (!isPowerOf2_64(Pow2Alignment))
1312         return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
1313       Pow2Alignment = Log2_64(Pow2Alignment);
1314     }
1315   }
1316   
1317   if (Lexer.isNot(AsmToken::EndOfStatement))
1318     return TokError("unexpected token in '.comm' or '.lcomm' directive");
1319   
1320   Lex();
1321
1322   // NOTE: a size of zero for a .comm should create a undefined symbol
1323   // but a size of .lcomm creates a bss symbol of size zero.
1324   if (Size < 0)
1325     return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
1326                  "be less than zero");
1327
1328   // NOTE: The alignment in the directive is a power of 2 value, the assembler
1329   // may internally end up wanting an alignment in bytes.
1330   // FIXME: Diagnose overflow.
1331   if (Pow2Alignment < 0)
1332     return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
1333                  "alignment, can't be less than zero");
1334
1335   if (!Sym->isUndefined())
1336     return Error(IDLoc, "invalid symbol redefinition");
1337
1338   // '.lcomm' is equivalent to '.zerofill'.
1339   // Create the Symbol as a common or local common with Size and Pow2Alignment
1340   if (IsLocal) {
1341     Out.EmitZerofill(Ctx.getMachOSection("__DATA", "__bss",
1342                                          MCSectionMachO::S_ZEROFILL, 0,
1343                                          SectionKind::getBSS()),
1344                      Sym, Size, 1 << Pow2Alignment);
1345     return false;
1346   }
1347
1348   Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
1349   return false;
1350 }
1351
1352 /// ParseDirectiveDarwinZerofill
1353 ///  ::= .zerofill segname , sectname [, identifier , size_expression [
1354 ///      , align_expression ]]
1355 bool AsmParser::ParseDirectiveDarwinZerofill() {
1356   StringRef Segment;
1357   if (ParseIdentifier(Segment))
1358     return TokError("expected segment name after '.zerofill' directive");
1359
1360   if (Lexer.isNot(AsmToken::Comma))
1361     return TokError("unexpected token in directive");
1362   Lex();
1363
1364   StringRef Section;
1365   if (ParseIdentifier(Section))
1366     return TokError("expected section name after comma in '.zerofill' "
1367                     "directive");
1368
1369   // If this is the end of the line all that was wanted was to create the
1370   // the section but with no symbol.
1371   if (Lexer.is(AsmToken::EndOfStatement)) {
1372     // Create the zerofill section but no symbol
1373     Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
1374                                          MCSectionMachO::S_ZEROFILL, 0,
1375                                          SectionKind::getBSS()));
1376     return false;
1377   }
1378
1379   if (Lexer.isNot(AsmToken::Comma))
1380     return TokError("unexpected token in directive");
1381   Lex();
1382
1383   SMLoc IDLoc = Lexer.getLoc();
1384   StringRef IDStr;
1385   if (ParseIdentifier(IDStr))
1386     return TokError("expected identifier in directive");
1387   
1388   // handle the identifier as the key symbol.
1389   MCSymbol *Sym = CreateSymbol(IDStr);
1390
1391   if (Lexer.isNot(AsmToken::Comma))
1392     return TokError("unexpected token in directive");
1393   Lex();
1394
1395   int64_t Size;
1396   SMLoc SizeLoc = Lexer.getLoc();
1397   if (ParseAbsoluteExpression(Size))
1398     return true;
1399
1400   int64_t Pow2Alignment = 0;
1401   SMLoc Pow2AlignmentLoc;
1402   if (Lexer.is(AsmToken::Comma)) {
1403     Lex();
1404     Pow2AlignmentLoc = Lexer.getLoc();
1405     if (ParseAbsoluteExpression(Pow2Alignment))
1406       return true;
1407   }
1408   
1409   if (Lexer.isNot(AsmToken::EndOfStatement))
1410     return TokError("unexpected token in '.zerofill' directive");
1411   
1412   Lex();
1413
1414   if (Size < 0)
1415     return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
1416                  "than zero");
1417
1418   // NOTE: The alignment in the directive is a power of 2 value, the assembler
1419   // may internally end up wanting an alignment in bytes.
1420   // FIXME: Diagnose overflow.
1421   if (Pow2Alignment < 0)
1422     return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
1423                  "can't be less than zero");
1424
1425   if (!Sym->isUndefined())
1426     return Error(IDLoc, "invalid symbol redefinition");
1427
1428   // Create the zerofill Symbol with Size and Pow2Alignment
1429   //
1430   // FIXME: Arch specific.
1431   Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
1432                                        MCSectionMachO::S_ZEROFILL, 0,
1433                                        SectionKind::getBSS()),
1434                    Sym, Size, 1 << Pow2Alignment);
1435
1436   return false;
1437 }
1438
1439 /// ParseDirectiveDarwinTBSS
1440 ///  ::= .tbss identifier, size, align
1441 bool AsmParser::ParseDirectiveDarwinTBSS() {
1442   SMLoc IDLoc = Lexer.getLoc();
1443   StringRef Name;
1444   if (ParseIdentifier(Name))
1445     return TokError("expected identifier in directive");
1446     
1447   // Handle the identifier as the key symbol.
1448   MCSymbol *Sym = CreateSymbol(Name);
1449
1450   if (Lexer.isNot(AsmToken::Comma))
1451     return TokError("unexpected token in directive");
1452   Lex();
1453
1454   int64_t Size;
1455   SMLoc SizeLoc = Lexer.getLoc();
1456   if (ParseAbsoluteExpression(Size))
1457     return true;
1458
1459   int64_t Pow2Alignment = 0;
1460   SMLoc Pow2AlignmentLoc;
1461   if (Lexer.is(AsmToken::Comma)) {
1462     Lex();
1463     Pow2AlignmentLoc = Lexer.getLoc();
1464     if (ParseAbsoluteExpression(Pow2Alignment))
1465       return true;
1466   }
1467   
1468   if (Lexer.isNot(AsmToken::EndOfStatement))
1469     return TokError("unexpected token in '.tbss' directive");
1470   
1471   Lex();
1472
1473   if (Size < 0)
1474     return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
1475                  "zero");
1476
1477   // FIXME: Diagnose overflow.
1478   if (Pow2Alignment < 0)
1479     return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
1480                  "than zero");
1481
1482   if (!Sym->isUndefined())
1483     return Error(IDLoc, "invalid symbol redefinition");
1484   
1485   Out.EmitTBSSSymbol(Sym, Size, Pow2Alignment ? 1 << Pow2Alignment : 0);
1486   
1487   return false;
1488 }
1489
1490 /// ParseDirectiveDarwinSubsectionsViaSymbols
1491 ///  ::= .subsections_via_symbols
1492 bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() {
1493   if (Lexer.isNot(AsmToken::EndOfStatement))
1494     return TokError("unexpected token in '.subsections_via_symbols' directive");
1495   
1496   Lex();
1497
1498   Out.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1499
1500   return false;
1501 }
1502
1503 /// ParseDirectiveAbort
1504 ///  ::= .abort [ "abort_string" ]
1505 bool AsmParser::ParseDirectiveAbort() {
1506   // FIXME: Use loc from directive.
1507   SMLoc Loc = Lexer.getLoc();
1508
1509   StringRef Str = "";
1510   if (Lexer.isNot(AsmToken::EndOfStatement)) {
1511     if (Lexer.isNot(AsmToken::String))
1512       return TokError("expected string in '.abort' directive");
1513     
1514     Str = getTok().getString();
1515
1516     Lex();
1517   }
1518
1519   if (Lexer.isNot(AsmToken::EndOfStatement))
1520     return TokError("unexpected token in '.abort' directive");
1521   
1522   Lex();
1523
1524   // FIXME: Handle here.
1525   if (Str.empty())
1526     Error(Loc, ".abort detected. Assembly stopping.");
1527   else
1528     Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
1529
1530   return false;
1531 }
1532
1533 /// ParseDirectiveLsym
1534 ///  ::= .lsym identifier , expression
1535 bool AsmParser::ParseDirectiveDarwinLsym() {
1536   StringRef Name;
1537   if (ParseIdentifier(Name))
1538     return TokError("expected identifier in directive");
1539   
1540   // Handle the identifier as the key symbol.
1541   MCSymbol *Sym = CreateSymbol(Name);
1542
1543   if (Lexer.isNot(AsmToken::Comma))
1544     return TokError("unexpected token in '.lsym' directive");
1545   Lex();
1546
1547   const MCExpr *Value;
1548   SMLoc StartLoc = Lexer.getLoc();
1549   if (ParseExpression(Value))
1550     return true;
1551
1552   if (Lexer.isNot(AsmToken::EndOfStatement))
1553     return TokError("unexpected token in '.lsym' directive");
1554   
1555   Lex();
1556
1557   // We don't currently support this directive.
1558   //
1559   // FIXME: Diagnostic location!
1560   (void) Sym;
1561   return TokError("directive '.lsym' is unsupported");
1562 }
1563
1564 /// ParseDirectiveInclude
1565 ///  ::= .include "filename"
1566 bool AsmParser::ParseDirectiveInclude() {
1567   if (Lexer.isNot(AsmToken::String))
1568     return TokError("expected string in '.include' directive");
1569   
1570   std::string Filename = getTok().getString();
1571   SMLoc IncludeLoc = Lexer.getLoc();
1572   Lex();
1573
1574   if (Lexer.isNot(AsmToken::EndOfStatement))
1575     return TokError("unexpected token in '.include' directive");
1576   
1577   // Strip the quotes.
1578   Filename = Filename.substr(1, Filename.size()-2);
1579   
1580   // Attempt to switch the lexer to the included file before consuming the end
1581   // of statement to avoid losing it when we switch.
1582   if (EnterIncludeFile(Filename)) {
1583     PrintMessage(IncludeLoc,
1584                  "Could not find include file '" + Filename + "'",
1585                  "error");
1586     return true;
1587   }
1588
1589   return false;
1590 }
1591
1592 /// ParseDirectiveDarwinDumpOrLoad
1593 ///  ::= ( .dump | .load ) "filename"
1594 bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
1595   if (Lexer.isNot(AsmToken::String))
1596     return TokError("expected string in '.dump' or '.load' directive");
1597   
1598   Lex();
1599
1600   if (Lexer.isNot(AsmToken::EndOfStatement))
1601     return TokError("unexpected token in '.dump' or '.load' directive");
1602   
1603   Lex();
1604
1605   // FIXME: If/when .dump and .load are implemented they will be done in the
1606   // the assembly parser and not have any need for an MCStreamer API.
1607   if (IsDump)
1608     Warning(IDLoc, "ignoring directive .dump for now");
1609   else
1610     Warning(IDLoc, "ignoring directive .load for now");
1611
1612   return false;
1613 }
1614
1615 /// ParseDirectiveIf
1616 /// ::= .if expression
1617 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
1618   TheCondStack.push_back(TheCondState);
1619   TheCondState.TheCond = AsmCond::IfCond;
1620   if(TheCondState.Ignore) {
1621     EatToEndOfStatement();
1622   }
1623   else {
1624     int64_t ExprValue;
1625     if (ParseAbsoluteExpression(ExprValue))
1626       return true;
1627
1628     if (Lexer.isNot(AsmToken::EndOfStatement))
1629       return TokError("unexpected token in '.if' directive");
1630     
1631     Lex();
1632
1633     TheCondState.CondMet = ExprValue;
1634     TheCondState.Ignore = !TheCondState.CondMet;
1635   }
1636
1637   return false;
1638 }
1639
1640 /// ParseDirectiveElseIf
1641 /// ::= .elseif expression
1642 bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
1643   if (TheCondState.TheCond != AsmCond::IfCond &&
1644       TheCondState.TheCond != AsmCond::ElseIfCond)
1645       Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
1646                           " an .elseif");
1647   TheCondState.TheCond = AsmCond::ElseIfCond;
1648
1649   bool LastIgnoreState = false;
1650   if (!TheCondStack.empty())
1651       LastIgnoreState = TheCondStack.back().Ignore;
1652   if (LastIgnoreState || TheCondState.CondMet) {
1653     TheCondState.Ignore = true;
1654     EatToEndOfStatement();
1655   }
1656   else {
1657     int64_t ExprValue;
1658     if (ParseAbsoluteExpression(ExprValue))
1659       return true;
1660
1661     if (Lexer.isNot(AsmToken::EndOfStatement))
1662       return TokError("unexpected token in '.elseif' directive");
1663     
1664     Lex();
1665     TheCondState.CondMet = ExprValue;
1666     TheCondState.Ignore = !TheCondState.CondMet;
1667   }
1668
1669   return false;
1670 }
1671
1672 /// ParseDirectiveElse
1673 /// ::= .else
1674 bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
1675   if (Lexer.isNot(AsmToken::EndOfStatement))
1676     return TokError("unexpected token in '.else' directive");
1677   
1678   Lex();
1679
1680   if (TheCondState.TheCond != AsmCond::IfCond &&
1681       TheCondState.TheCond != AsmCond::ElseIfCond)
1682       Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
1683                           ".elseif");
1684   TheCondState.TheCond = AsmCond::ElseCond;
1685   bool LastIgnoreState = false;
1686   if (!TheCondStack.empty())
1687     LastIgnoreState = TheCondStack.back().Ignore;
1688   if (LastIgnoreState || TheCondState.CondMet)
1689     TheCondState.Ignore = true;
1690   else
1691     TheCondState.Ignore = false;
1692
1693   return false;
1694 }
1695
1696 /// ParseDirectiveEndIf
1697 /// ::= .endif
1698 bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
1699   if (Lexer.isNot(AsmToken::EndOfStatement))
1700     return TokError("unexpected token in '.endif' directive");
1701   
1702   Lex();
1703
1704   if ((TheCondState.TheCond == AsmCond::NoCond) ||
1705       TheCondStack.empty())
1706     Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
1707                         ".else");
1708   if (!TheCondStack.empty()) {
1709     TheCondState = TheCondStack.back();
1710     TheCondStack.pop_back();
1711   }
1712
1713   return false;
1714 }
1715
1716 /// ParseDirectiveFile
1717 /// ::= .file [number] string
1718 bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
1719   // FIXME: I'm not sure what this is.
1720   int64_t FileNumber = -1;
1721   if (Lexer.is(AsmToken::Integer)) {
1722     FileNumber = getTok().getIntVal();
1723     Lex();
1724     
1725     if (FileNumber < 1)
1726       return TokError("file number less than one");
1727   }
1728
1729   if (Lexer.isNot(AsmToken::String))
1730     return TokError("unexpected token in '.file' directive");
1731   
1732   StringRef Filename = getTok().getString();
1733   Filename = Filename.substr(1, Filename.size()-2);
1734   Lex();
1735
1736   if (Lexer.isNot(AsmToken::EndOfStatement))
1737     return TokError("unexpected token in '.file' directive");
1738
1739   if (FileNumber == -1)
1740     Out.EmitFileDirective(Filename);
1741   else
1742     Out.EmitDwarfFileDirective(FileNumber, Filename);
1743   
1744   return false;
1745 }
1746
1747 /// ParseDirectiveLine
1748 /// ::= .line [number]
1749 bool AsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
1750   if (Lexer.isNot(AsmToken::EndOfStatement)) {
1751     if (Lexer.isNot(AsmToken::Integer))
1752       return TokError("unexpected token in '.line' directive");
1753
1754     int64_t LineNumber = getTok().getIntVal();
1755     (void) LineNumber;
1756     Lex();
1757
1758     // FIXME: Do something with the .line.
1759   }
1760
1761   if (Lexer.isNot(AsmToken::EndOfStatement))
1762     return TokError("unexpected token in '.file' directive");
1763
1764   return false;
1765 }
1766
1767
1768 /// ParseDirectiveLoc
1769 /// ::= .loc number [number [number]]
1770 bool AsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
1771   if (Lexer.isNot(AsmToken::Integer))
1772     return TokError("unexpected token in '.loc' directive");
1773
1774   // FIXME: What are these fields?
1775   int64_t FileNumber = getTok().getIntVal();
1776   (void) FileNumber;
1777   // FIXME: Validate file.
1778
1779   Lex();
1780   if (Lexer.isNot(AsmToken::EndOfStatement)) {
1781     if (Lexer.isNot(AsmToken::Integer))
1782       return TokError("unexpected token in '.loc' directive");
1783
1784     int64_t Param2 = getTok().getIntVal();
1785     (void) Param2;
1786     Lex();
1787
1788     if (Lexer.isNot(AsmToken::EndOfStatement)) {
1789       if (Lexer.isNot(AsmToken::Integer))
1790         return TokError("unexpected token in '.loc' directive");
1791
1792       int64_t Param3 = getTok().getIntVal();
1793       (void) Param3;
1794       Lex();
1795
1796       // FIXME: Do something with the .loc.
1797     }
1798   }
1799
1800   if (Lexer.isNot(AsmToken::EndOfStatement))
1801     return TokError("unexpected token in '.file' directive");
1802
1803   return false;
1804 }
1805