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