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