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