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