AsmParser.cpp revision d9b0b025612992a0b724eeca8bdf10b1d7a5c355
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/APFloat.h"
15#include "llvm/ADT/SmallString.h"
16#include "llvm/ADT/StringMap.h"
17#include "llvm/ADT/Twine.h"
18#include "llvm/MC/MCAsmInfo.h"
19#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCDwarf.h"
21#include "llvm/MC/MCExpr.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/MCRegisterInfo.h"
27#include "llvm/MC/MCSectionMachO.h"
28#include "llvm/MC/MCStreamer.h"
29#include "llvm/MC/MCSymbol.h"
30#include "llvm/MC/MCTargetAsmParser.h"
31#include "llvm/Support/CommandLine.h"
32#include "llvm/Support/ErrorHandling.h"
33#include "llvm/Support/MathExtras.h"
34#include "llvm/Support/MemoryBuffer.h"
35#include "llvm/Support/SourceMgr.h"
36#include "llvm/Support/raw_ostream.h"
37#include <cctype>
38#include <vector>
39using namespace llvm;
40
41static cl::opt<bool>
42FatalAssemblerWarnings("fatal-assembler-warnings",
43                       cl::desc("Consider warnings as error"));
44
45namespace {
46
47/// \brief Helper class for tracking macro definitions.
48struct Macro {
49  StringRef Name;
50  StringRef Body;
51  std::vector<StringRef> Parameters;
52
53public:
54  Macro(StringRef N, StringRef B, const std::vector<StringRef> &P) :
55    Name(N), Body(B), Parameters(P) {}
56};
57
58/// \brief Helper class for storing information about an active macro
59/// instantiation.
60struct MacroInstantiation {
61  /// The macro being instantiated.
62  const Macro *TheMacro;
63
64  /// The macro instantiation with substitutions.
65  MemoryBuffer *Instantiation;
66
67  /// The location of the instantiation.
68  SMLoc InstantiationLoc;
69
70  /// The location where parsing should resume upon instantiation completion.
71  SMLoc ExitLoc;
72
73public:
74  MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL,
75                     MemoryBuffer *I);
76};
77
78/// \brief The concrete assembly parser instance.
79class AsmParser : public MCAsmParser {
80  friend class GenericAsmParser;
81
82  AsmParser(const AsmParser &);   // DO NOT IMPLEMENT
83  void operator=(const AsmParser &);  // DO NOT IMPLEMENT
84private:
85  AsmLexer Lexer;
86  MCContext &Ctx;
87  MCStreamer &Out;
88  const MCAsmInfo &MAI;
89  SourceMgr &SrcMgr;
90  SourceMgr::DiagHandlerTy SavedDiagHandler;
91  void *SavedDiagContext;
92  MCAsmParserExtension *GenericParser;
93  MCAsmParserExtension *PlatformParser;
94
95  /// This is the current buffer index we're lexing from as managed by the
96  /// SourceMgr object.
97  int CurBuffer;
98
99  AsmCond TheCondState;
100  std::vector<AsmCond> TheCondStack;
101
102  /// DirectiveMap - This is a table handlers for directives.  Each handler is
103  /// invoked after the directive identifier is read and is responsible for
104  /// parsing and validating the rest of the directive.  The handler is passed
105  /// in the directive name and the location of the directive keyword.
106  StringMap<std::pair<MCAsmParserExtension*, DirectiveHandler> > DirectiveMap;
107
108  /// MacroMap - Map of currently defined macros.
109  StringMap<Macro*> MacroMap;
110
111  /// ActiveMacros - Stack of active macro instantiations.
112  std::vector<MacroInstantiation*> ActiveMacros;
113
114  /// ActiveRept - Stack of active .rept directives.
115  std::vector<SMLoc> ActiveRept;
116
117  /// Boolean tracking whether macro substitution is enabled.
118  unsigned MacrosEnabled : 1;
119
120  /// Flag tracking whether any errors have been encountered.
121  unsigned HadError : 1;
122
123  /// The values from the last parsed cpp hash file line comment if any.
124  StringRef CppHashFilename;
125  int64_t CppHashLineNumber;
126  SMLoc CppHashLoc;
127
128  /// AssemblerDialect. ~OU means unset value and use value provided by MAI.
129  unsigned AssemblerDialect;
130
131public:
132  AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
133            const MCAsmInfo &MAI);
134  ~AsmParser();
135
136  virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false);
137
138  void AddDirectiveHandler(MCAsmParserExtension *Object,
139                           StringRef Directive,
140                           DirectiveHandler Handler) {
141    DirectiveMap[Directive] = std::make_pair(Object, Handler);
142  }
143
144public:
145  /// @name MCAsmParser Interface
146  /// {
147
148  virtual SourceMgr &getSourceManager() { return SrcMgr; }
149  virtual MCAsmLexer &getLexer() { return Lexer; }
150  virtual MCContext &getContext() { return Ctx; }
151  virtual MCStreamer &getStreamer() { return Out; }
152  virtual unsigned getAssemblerDialect() {
153    if (AssemblerDialect == ~0U)
154      return MAI.getAssemblerDialect();
155    else
156      return AssemblerDialect;
157  }
158  virtual void setAssemblerDialect(unsigned i) {
159    AssemblerDialect = i;
160  }
161
162  virtual bool Warning(SMLoc L, const Twine &Msg,
163                       ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
164  virtual bool Error(SMLoc L, const Twine &Msg,
165                     ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
166
167  const AsmToken &Lex();
168
169  bool ParseExpression(const MCExpr *&Res);
170  virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc);
171  virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
172  virtual bool ParseAbsoluteExpression(int64_t &Res);
173
174  /// }
175
176private:
177  void CheckForValidSection();
178
179  bool ParseStatement();
180  void EatToEndOfLine();
181  bool ParseCppHashLineFilenameComment(const SMLoc &L);
182
183  bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M);
184  bool expandMacro(SmallString<256> &Buf, StringRef Body,
185                   const std::vector<StringRef> &Parameters,
186                   const std::vector<std::vector<AsmToken> > &A,
187                   const SMLoc &L);
188  void HandleMacroExit();
189
190  void PrintMacroInstantiations();
191  void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
192                    ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const {
193    SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
194  }
195  static void DiagHandler(const SMDiagnostic &Diag, void *Context);
196
197  /// EnterIncludeFile - Enter the specified file. This returns true on failure.
198  bool EnterIncludeFile(const std::string &Filename);
199  /// ProcessIncbinFile - Process the specified file for the .incbin directive.
200  /// This returns true on failure.
201  bool ProcessIncbinFile(const std::string &Filename);
202
203  /// \brief Reset the current lexer position to that given by \arg Loc. The
204  /// current token is not set; clients should ensure Lex() is called
205  /// subsequently.
206  void JumpToLoc(SMLoc Loc);
207
208  void EatToEndOfStatement();
209
210  /// \brief Parse up to the end of statement and a return the contents from the
211  /// current token until the end of the statement; the current token on exit
212  /// will be either the EndOfStatement or EOF.
213  StringRef ParseStringToEndOfStatement();
214
215  /// \brief Parse until the end of a statement or a comma is encountered,
216  /// return the contents from the current token up to the end or comma.
217  StringRef ParseStringToComma();
218
219  bool ParseAssignment(StringRef Name, bool allow_redef);
220
221  bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
222  bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
223  bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
224  bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
225
226  /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
227  /// and set \arg Res to the identifier contents.
228  bool ParseIdentifier(StringRef &Res);
229
230  // Directive Parsing.
231
232 // ".ascii", ".asciiz", ".string"
233  bool ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
234  bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
235  bool ParseDirectiveRealValue(const fltSemantics &); // ".single", ...
236  bool ParseDirectiveFill(); // ".fill"
237  bool ParseDirectiveSpace(); // ".space"
238  bool ParseDirectiveZero(); // ".zero"
239  bool ParseDirectiveSet(StringRef IDVal, bool allow_redef); // ".set", ".equ", ".equiv"
240  bool ParseDirectiveOrg(); // ".org"
241  // ".align{,32}", ".p2align{,w,l}"
242  bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
243
244  /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
245  /// accepts a single symbol (which should be a label or an external).
246  bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr);
247
248  bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
249
250  bool ParseDirectiveAbort(); // ".abort"
251  bool ParseDirectiveInclude(); // ".include"
252  bool ParseDirectiveIncbin(); // ".incbin"
253
254  bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if"
255  // ".ifb" or ".ifnb", depending on ExpectBlank.
256  bool ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
257  // ".ifc" or ".ifnc", depending on ExpectEqual.
258  bool ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual);
259  // ".ifdef" or ".ifndef", depending on expect_defined
260  bool ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
261  bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
262  bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else"
263  bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
264
265  /// ParseEscapedString - Parse the current token as a string which may include
266  /// escaped characters and return the string contents.
267  bool ParseEscapedString(std::string &Data);
268
269  const MCExpr *ApplyModifierToExpr(const MCExpr *E,
270                                    MCSymbolRefExpr::VariantKind Variant);
271
272  bool ParseDirectiveRept(SMLoc DirectiveLoc);
273  bool ParseDirectiveEndRept(SMLoc DirectiveLoc);
274};
275
276/// \brief Generic implementations of directive handling, etc. which is shared
277/// (or the default, at least) for all assembler parser.
278class GenericAsmParser : public MCAsmParserExtension {
279  template<bool (GenericAsmParser::*Handler)(StringRef, SMLoc)>
280  void AddDirectiveHandler(StringRef Directive) {
281    getParser().AddDirectiveHandler(this, Directive,
282                                    HandleDirective<GenericAsmParser, Handler>);
283  }
284public:
285  GenericAsmParser() {}
286
287  AsmParser &getParser() {
288    return (AsmParser&) this->MCAsmParserExtension::getParser();
289  }
290
291  virtual void Initialize(MCAsmParser &Parser) {
292    // Call the base implementation.
293    this->MCAsmParserExtension::Initialize(Parser);
294
295    // Debugging directives.
296    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveFile>(".file");
297    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLine>(".line");
298    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLoc>(".loc");
299    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveStabs>(".stabs");
300
301    // CFI directives.
302    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFISections>(
303                                                               ".cfi_sections");
304    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIStartProc>(
305                                                              ".cfi_startproc");
306    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIEndProc>(
307                                                                ".cfi_endproc");
308    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfa>(
309                                                         ".cfi_def_cfa");
310    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset>(
311                                                         ".cfi_def_cfa_offset");
312    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset>(
313                                                      ".cfi_adjust_cfa_offset");
314    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister>(
315                                                       ".cfi_def_cfa_register");
316    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIOffset>(
317                                                                 ".cfi_offset");
318    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIRelOffset>(
319                                                             ".cfi_rel_offset");
320    AddDirectiveHandler<
321     &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_personality");
322    AddDirectiveHandler<
323            &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_lsda");
324    AddDirectiveHandler<
325      &GenericAsmParser::ParseDirectiveCFIRememberState>(".cfi_remember_state");
326    AddDirectiveHandler<
327      &GenericAsmParser::ParseDirectiveCFIRestoreState>(".cfi_restore_state");
328    AddDirectiveHandler<
329      &GenericAsmParser::ParseDirectiveCFISameValue>(".cfi_same_value");
330    AddDirectiveHandler<
331      &GenericAsmParser::ParseDirectiveCFIRestore>(".cfi_restore");
332    AddDirectiveHandler<
333      &GenericAsmParser::ParseDirectiveCFIEscape>(".cfi_escape");
334    AddDirectiveHandler<
335      &GenericAsmParser::ParseDirectiveCFISignalFrame>(".cfi_signal_frame");
336
337    // Macro directives.
338    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
339      ".macros_on");
340    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
341      ".macros_off");
342    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacro>(".macro");
343    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endm");
344    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endmacro");
345    AddDirectiveHandler<&GenericAsmParser::ParseDirectivePurgeMacro>(".purgem");
346
347    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".sleb128");
348    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".uleb128");
349  }
350
351  bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
352
353  bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc);
354  bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc);
355  bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc);
356  bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc);
357  bool ParseDirectiveCFISections(StringRef, SMLoc DirectiveLoc);
358  bool ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc);
359  bool ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc);
360  bool ParseDirectiveCFIDefCfa(StringRef, SMLoc DirectiveLoc);
361  bool ParseDirectiveCFIDefCfaOffset(StringRef, SMLoc DirectiveLoc);
362  bool ParseDirectiveCFIAdjustCfaOffset(StringRef, SMLoc DirectiveLoc);
363  bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc);
364  bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc);
365  bool ParseDirectiveCFIRelOffset(StringRef, SMLoc DirectiveLoc);
366  bool ParseDirectiveCFIPersonalityOrLsda(StringRef, SMLoc DirectiveLoc);
367  bool ParseDirectiveCFIRememberState(StringRef, SMLoc DirectiveLoc);
368  bool ParseDirectiveCFIRestoreState(StringRef, SMLoc DirectiveLoc);
369  bool ParseDirectiveCFISameValue(StringRef, SMLoc DirectiveLoc);
370  bool ParseDirectiveCFIRestore(StringRef, SMLoc DirectiveLoc);
371  bool ParseDirectiveCFIEscape(StringRef, SMLoc DirectiveLoc);
372  bool ParseDirectiveCFISignalFrame(StringRef, SMLoc DirectiveLoc);
373
374  bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc);
375  bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
376  bool ParseDirectiveEndMacro(StringRef, SMLoc DirectiveLoc);
377  bool ParseDirectivePurgeMacro(StringRef, SMLoc DirectiveLoc);
378
379  bool ParseDirectiveLEB128(StringRef, SMLoc);
380};
381
382}
383
384namespace llvm {
385
386extern MCAsmParserExtension *createDarwinAsmParser();
387extern MCAsmParserExtension *createELFAsmParser();
388extern MCAsmParserExtension *createCOFFAsmParser();
389
390}
391
392enum { DEFAULT_ADDRSPACE = 0 };
393
394AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
395                     MCStreamer &_Out, const MCAsmInfo &_MAI)
396  : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
397    GenericParser(new GenericAsmParser), PlatformParser(0),
398    CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0),
399    AssemblerDialect(~0U) {
400  // Save the old handler.
401  SavedDiagHandler = SrcMgr.getDiagHandler();
402  SavedDiagContext = SrcMgr.getDiagContext();
403  // Set our own handler which calls the saved handler.
404  SrcMgr.setDiagHandler(DiagHandler, this);
405  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
406
407  // Initialize the generic parser.
408  GenericParser->Initialize(*this);
409
410  // Initialize the platform / file format parser.
411  //
412  // FIXME: This is a hack, we need to (majorly) cleanup how these objects are
413  // created.
414  if (_MAI.hasMicrosoftFastStdCallMangling()) {
415    PlatformParser = createCOFFAsmParser();
416    PlatformParser->Initialize(*this);
417  } else if (_MAI.hasSubsectionsViaSymbols()) {
418    PlatformParser = createDarwinAsmParser();
419    PlatformParser->Initialize(*this);
420  } else {
421    PlatformParser = createELFAsmParser();
422    PlatformParser->Initialize(*this);
423  }
424}
425
426AsmParser::~AsmParser() {
427  assert(ActiveMacros.empty() && "Unexpected active macro instantiation!");
428
429  // Destroy any macros.
430  for (StringMap<Macro*>::iterator it = MacroMap.begin(),
431         ie = MacroMap.end(); it != ie; ++it)
432    delete it->getValue();
433
434  delete PlatformParser;
435  delete GenericParser;
436}
437
438void AsmParser::PrintMacroInstantiations() {
439  // Print the active macro instantiation stack.
440  for (std::vector<MacroInstantiation*>::const_reverse_iterator
441         it = ActiveMacros.rbegin(), ie = ActiveMacros.rend(); it != ie; ++it)
442    PrintMessage((*it)->InstantiationLoc, SourceMgr::DK_Note,
443                 "while in macro instantiation");
444}
445
446bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
447  if (FatalAssemblerWarnings)
448    return Error(L, Msg, Ranges);
449  PrintMessage(L, SourceMgr::DK_Warning, Msg, Ranges);
450  PrintMacroInstantiations();
451  return false;
452}
453
454bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
455  HadError = true;
456  PrintMessage(L, SourceMgr::DK_Error, Msg, Ranges);
457  PrintMacroInstantiations();
458  return true;
459}
460
461bool AsmParser::EnterIncludeFile(const std::string &Filename) {
462  std::string IncludedFile;
463  int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
464  if (NewBuf == -1)
465    return true;
466
467  CurBuffer = NewBuf;
468
469  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
470
471  return false;
472}
473
474/// Process the specified .incbin file by seaching for it in the include paths
475/// then just emitting the byte contents of the file to the streamer. This
476/// returns true on failure.
477bool AsmParser::ProcessIncbinFile(const std::string &Filename) {
478  std::string IncludedFile;
479  int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
480  if (NewBuf == -1)
481    return true;
482
483  // Pick up the bytes from the file and emit them.
484  getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer(),
485                          DEFAULT_ADDRSPACE);
486  return false;
487}
488
489void AsmParser::JumpToLoc(SMLoc Loc) {
490  CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
491  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), Loc.getPointer());
492}
493
494const AsmToken &AsmParser::Lex() {
495  const AsmToken *tok = &Lexer.Lex();
496
497  if (tok->is(AsmToken::Eof)) {
498    // If this is the end of an included file, pop the parent file off the
499    // include stack.
500    SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
501    if (ParentIncludeLoc != SMLoc()) {
502      JumpToLoc(ParentIncludeLoc);
503      tok = &Lexer.Lex();
504    }
505  }
506
507  if (tok->is(AsmToken::Error))
508    Error(Lexer.getErrLoc(), Lexer.getErr());
509
510  return *tok;
511}
512
513bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
514  // Create the initial section, if requested.
515  if (!NoInitialTextSection)
516    Out.InitSections();
517
518  // Prime the lexer.
519  Lex();
520
521  HadError = false;
522  AsmCond StartingCondState = TheCondState;
523
524  // If we are generating dwarf for assembly source files save the initial text
525  // section and generate a .file directive.
526  if (getContext().getGenDwarfForAssembly()) {
527    getContext().setGenDwarfSection(getStreamer().getCurrentSection());
528    MCSymbol *SectionStartSym = getContext().CreateTempSymbol();
529    getStreamer().EmitLabel(SectionStartSym);
530    getContext().setGenDwarfSectionStartSym(SectionStartSym);
531    getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(),
532      StringRef(), SrcMgr.getMemoryBuffer(CurBuffer)->getBufferIdentifier());
533  }
534
535  // While we have input, parse each statement.
536  while (Lexer.isNot(AsmToken::Eof)) {
537    if (!ParseStatement()) continue;
538
539    // We had an error, validate that one was emitted and recover by skipping to
540    // the next line.
541    assert(HadError && "Parse statement returned an error, but none emitted!");
542    EatToEndOfStatement();
543  }
544
545  if (TheCondState.TheCond != StartingCondState.TheCond ||
546      TheCondState.Ignore != StartingCondState.Ignore)
547    return TokError("unmatched .ifs or .elses");
548
549  // Check to see there are no empty DwarfFile slots.
550  const std::vector<MCDwarfFile *> &MCDwarfFiles =
551    getContext().getMCDwarfFiles();
552  for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
553    if (!MCDwarfFiles[i])
554      TokError("unassigned file number: " + Twine(i) + " for .file directives");
555  }
556
557  // Check to see that all assembler local symbols were actually defined.
558  // Targets that don't do subsections via symbols may not want this, though,
559  // so conservatively exclude them. Only do this if we're finalizing, though,
560  // as otherwise we won't necessarilly have seen everything yet.
561  if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) {
562    const MCContext::SymbolTable &Symbols = getContext().getSymbols();
563    for (MCContext::SymbolTable::const_iterator i = Symbols.begin(),
564         e = Symbols.end();
565         i != e; ++i) {
566      MCSymbol *Sym = i->getValue();
567      // Variable symbols may not be marked as defined, so check those
568      // explicitly. If we know it's a variable, we have a definition for
569      // the purposes of this check.
570      if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
571        // FIXME: We would really like to refer back to where the symbol was
572        // first referenced for a source location. We need to add something
573        // to track that. Currently, we just point to the end of the file.
574        PrintMessage(getLexer().getLoc(), SourceMgr::DK_Error,
575                     "assembler local symbol '" + Sym->getName() +
576                     "' not defined");
577    }
578  }
579
580
581  // Finalize the output stream if there are no errors and if the client wants
582  // us to.
583  if (!HadError && !NoFinalize)
584    Out.Finish();
585
586  return HadError;
587}
588
589void AsmParser::CheckForValidSection() {
590  if (!getStreamer().getCurrentSection()) {
591    TokError("expected section directive before assembly directive");
592    Out.SwitchSection(Ctx.getMachOSection(
593                        "__TEXT", "__text",
594                        MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
595                        0, SectionKind::getText()));
596  }
597}
598
599/// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
600void AsmParser::EatToEndOfStatement() {
601  while (Lexer.isNot(AsmToken::EndOfStatement) &&
602         Lexer.isNot(AsmToken::Eof))
603    Lex();
604
605  // Eat EOL.
606  if (Lexer.is(AsmToken::EndOfStatement))
607    Lex();
608}
609
610StringRef AsmParser::ParseStringToEndOfStatement() {
611  const char *Start = getTok().getLoc().getPointer();
612
613  while (Lexer.isNot(AsmToken::EndOfStatement) &&
614         Lexer.isNot(AsmToken::Eof))
615    Lex();
616
617  const char *End = getTok().getLoc().getPointer();
618  return StringRef(Start, End - Start);
619}
620
621StringRef AsmParser::ParseStringToComma() {
622  const char *Start = getTok().getLoc().getPointer();
623
624  while (Lexer.isNot(AsmToken::EndOfStatement) &&
625         Lexer.isNot(AsmToken::Comma) &&
626         Lexer.isNot(AsmToken::Eof))
627    Lex();
628
629  const char *End = getTok().getLoc().getPointer();
630  return StringRef(Start, End - Start);
631}
632
633/// ParseParenExpr - Parse a paren expression and return it.
634/// NOTE: This assumes the leading '(' has already been consumed.
635///
636/// parenexpr ::= expr)
637///
638bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
639  if (ParseExpression(Res)) return true;
640  if (Lexer.isNot(AsmToken::RParen))
641    return TokError("expected ')' in parentheses expression");
642  EndLoc = Lexer.getLoc();
643  Lex();
644  return false;
645}
646
647/// ParseBracketExpr - Parse a bracket expression and return it.
648/// NOTE: This assumes the leading '[' has already been consumed.
649///
650/// bracketexpr ::= expr]
651///
652bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
653  if (ParseExpression(Res)) return true;
654  if (Lexer.isNot(AsmToken::RBrac))
655    return TokError("expected ']' in brackets expression");
656  EndLoc = Lexer.getLoc();
657  Lex();
658  return false;
659}
660
661/// ParsePrimaryExpr - Parse a primary expression and return it.
662///  primaryexpr ::= (parenexpr
663///  primaryexpr ::= symbol
664///  primaryexpr ::= number
665///  primaryexpr ::= '.'
666///  primaryexpr ::= ~,+,- primaryexpr
667bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
668  switch (Lexer.getKind()) {
669  default:
670    return TokError("unknown token in expression");
671  // If we have an error assume that we've already handled it.
672  case AsmToken::Error:
673    return true;
674  case AsmToken::Exclaim:
675    Lex(); // Eat the operator.
676    if (ParsePrimaryExpr(Res, EndLoc))
677      return true;
678    Res = MCUnaryExpr::CreateLNot(Res, getContext());
679    return false;
680  case AsmToken::Dollar:
681  case AsmToken::String:
682  case AsmToken::Identifier: {
683    EndLoc = Lexer.getLoc();
684
685    StringRef Identifier;
686    if (ParseIdentifier(Identifier))
687      return true;
688
689    // This is a symbol reference.
690    std::pair<StringRef, StringRef> Split = Identifier.split('@');
691    MCSymbol *Sym = getContext().GetOrCreateSymbol(Split.first);
692
693    // Lookup the symbol variant if used.
694    MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
695    if (Split.first.size() != Identifier.size()) {
696      Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
697      if (Variant == MCSymbolRefExpr::VK_Invalid) {
698        Variant = MCSymbolRefExpr::VK_None;
699        return TokError("invalid variant '" + Split.second + "'");
700      }
701    }
702
703    // If this is an absolute variable reference, substitute it now to preserve
704    // semantics in the face of reassignment.
705    if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) {
706      if (Variant)
707        return Error(EndLoc, "unexpected modifier on variable reference");
708
709      Res = Sym->getVariableValue();
710      return false;
711    }
712
713    // Otherwise create a symbol ref.
714    Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
715    return false;
716  }
717  case AsmToken::Integer: {
718    SMLoc Loc = getTok().getLoc();
719    int64_t IntVal = getTok().getIntVal();
720    Res = MCConstantExpr::Create(IntVal, getContext());
721    EndLoc = Lexer.getLoc();
722    Lex(); // Eat token.
723    // Look for 'b' or 'f' following an Integer as a directional label
724    if (Lexer.getKind() == AsmToken::Identifier) {
725      StringRef IDVal = getTok().getString();
726      if (IDVal == "f" || IDVal == "b"){
727        MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal,
728                                                      IDVal == "f" ? 1 : 0);
729        Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
730                                      getContext());
731        if (IDVal == "b" && Sym->isUndefined())
732          return Error(Loc, "invalid reference to undefined symbol");
733        EndLoc = Lexer.getLoc();
734        Lex(); // Eat identifier.
735      }
736    }
737    return false;
738  }
739  case AsmToken::Real: {
740    APFloat RealVal(APFloat::IEEEdouble, getTok().getString());
741    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
742    Res = MCConstantExpr::Create(IntVal, getContext());
743    Lex(); // Eat token.
744    return false;
745  }
746  case AsmToken::Dot: {
747    // This is a '.' reference, which references the current PC.  Emit a
748    // temporary label to the streamer and refer to it.
749    MCSymbol *Sym = Ctx.CreateTempSymbol();
750    Out.EmitLabel(Sym);
751    Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
752    EndLoc = Lexer.getLoc();
753    Lex(); // Eat identifier.
754    return false;
755  }
756  case AsmToken::LParen:
757    Lex(); // Eat the '('.
758    return ParseParenExpr(Res, EndLoc);
759  case AsmToken::LBrac:
760    if (!PlatformParser->HasBracketExpressions())
761      return TokError("brackets expression not supported on this target");
762    Lex(); // Eat the '['.
763    return ParseBracketExpr(Res, EndLoc);
764  case AsmToken::Minus:
765    Lex(); // Eat the operator.
766    if (ParsePrimaryExpr(Res, EndLoc))
767      return true;
768    Res = MCUnaryExpr::CreateMinus(Res, getContext());
769    return false;
770  case AsmToken::Plus:
771    Lex(); // Eat the operator.
772    if (ParsePrimaryExpr(Res, EndLoc))
773      return true;
774    Res = MCUnaryExpr::CreatePlus(Res, getContext());
775    return false;
776  case AsmToken::Tilde:
777    Lex(); // Eat the operator.
778    if (ParsePrimaryExpr(Res, EndLoc))
779      return true;
780    Res = MCUnaryExpr::CreateNot(Res, getContext());
781    return false;
782  }
783}
784
785bool AsmParser::ParseExpression(const MCExpr *&Res) {
786  SMLoc EndLoc;
787  return ParseExpression(Res, EndLoc);
788}
789
790const MCExpr *
791AsmParser::ApplyModifierToExpr(const MCExpr *E,
792                               MCSymbolRefExpr::VariantKind Variant) {
793  // Recurse over the given expression, rebuilding it to apply the given variant
794  // if there is exactly one symbol.
795  switch (E->getKind()) {
796  case MCExpr::Target:
797  case MCExpr::Constant:
798    return 0;
799
800  case MCExpr::SymbolRef: {
801    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
802
803    if (SRE->getKind() != MCSymbolRefExpr::VK_None) {
804      TokError("invalid variant on expression '" +
805               getTok().getIdentifier() + "' (already modified)");
806      return E;
807    }
808
809    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
810  }
811
812  case MCExpr::Unary: {
813    const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
814    const MCExpr *Sub = ApplyModifierToExpr(UE->getSubExpr(), Variant);
815    if (!Sub)
816      return 0;
817    return MCUnaryExpr::Create(UE->getOpcode(), Sub, getContext());
818  }
819
820  case MCExpr::Binary: {
821    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
822    const MCExpr *LHS = ApplyModifierToExpr(BE->getLHS(), Variant);
823    const MCExpr *RHS = ApplyModifierToExpr(BE->getRHS(), Variant);
824
825    if (!LHS && !RHS)
826      return 0;
827
828    if (!LHS) LHS = BE->getLHS();
829    if (!RHS) RHS = BE->getRHS();
830
831    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
832  }
833  }
834
835  llvm_unreachable("Invalid expression kind!");
836}
837
838/// ParseExpression - Parse an expression and return it.
839///
840///  expr ::= expr &&,|| expr               -> lowest.
841///  expr ::= expr |,^,&,! expr
842///  expr ::= expr ==,!=,<>,<,<=,>,>= expr
843///  expr ::= expr <<,>> expr
844///  expr ::= expr +,- expr
845///  expr ::= expr *,/,% expr               -> highest.
846///  expr ::= primaryexpr
847///
848bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
849  // Parse the expression.
850  Res = 0;
851  if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
852    return true;
853
854  // As a special case, we support 'a op b @ modifier' by rewriting the
855  // expression to include the modifier. This is inefficient, but in general we
856  // expect users to use 'a@modifier op b'.
857  if (Lexer.getKind() == AsmToken::At) {
858    Lex();
859
860    if (Lexer.isNot(AsmToken::Identifier))
861      return TokError("unexpected symbol modifier following '@'");
862
863    MCSymbolRefExpr::VariantKind Variant =
864      MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier());
865    if (Variant == MCSymbolRefExpr::VK_Invalid)
866      return TokError("invalid variant '" + getTok().getIdentifier() + "'");
867
868    const MCExpr *ModifiedRes = ApplyModifierToExpr(Res, Variant);
869    if (!ModifiedRes) {
870      return TokError("invalid modifier '" + getTok().getIdentifier() +
871                      "' (no symbols present)");
872    }
873
874    Res = ModifiedRes;
875    Lex();
876  }
877
878  // Try to constant fold it up front, if possible.
879  int64_t Value;
880  if (Res->EvaluateAsAbsolute(Value))
881    Res = MCConstantExpr::Create(Value, getContext());
882
883  return false;
884}
885
886bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
887  Res = 0;
888  return ParseParenExpr(Res, EndLoc) ||
889         ParseBinOpRHS(1, Res, EndLoc);
890}
891
892bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
893  const MCExpr *Expr;
894
895  SMLoc StartLoc = Lexer.getLoc();
896  if (ParseExpression(Expr))
897    return true;
898
899  if (!Expr->EvaluateAsAbsolute(Res))
900    return Error(StartLoc, "expected absolute expression");
901
902  return false;
903}
904
905static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
906                                   MCBinaryExpr::Opcode &Kind) {
907  switch (K) {
908  default:
909    return 0;    // not a binop.
910
911    // Lowest Precedence: &&, ||
912  case AsmToken::AmpAmp:
913    Kind = MCBinaryExpr::LAnd;
914    return 1;
915  case AsmToken::PipePipe:
916    Kind = MCBinaryExpr::LOr;
917    return 1;
918
919
920    // Low Precedence: |, &, ^
921    //
922    // FIXME: gas seems to support '!' as an infix operator?
923  case AsmToken::Pipe:
924    Kind = MCBinaryExpr::Or;
925    return 2;
926  case AsmToken::Caret:
927    Kind = MCBinaryExpr::Xor;
928    return 2;
929  case AsmToken::Amp:
930    Kind = MCBinaryExpr::And;
931    return 2;
932
933    // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >=
934  case AsmToken::EqualEqual:
935    Kind = MCBinaryExpr::EQ;
936    return 3;
937  case AsmToken::ExclaimEqual:
938  case AsmToken::LessGreater:
939    Kind = MCBinaryExpr::NE;
940    return 3;
941  case AsmToken::Less:
942    Kind = MCBinaryExpr::LT;
943    return 3;
944  case AsmToken::LessEqual:
945    Kind = MCBinaryExpr::LTE;
946    return 3;
947  case AsmToken::Greater:
948    Kind = MCBinaryExpr::GT;
949    return 3;
950  case AsmToken::GreaterEqual:
951    Kind = MCBinaryExpr::GTE;
952    return 3;
953
954    // Intermediate Precedence: <<, >>
955  case AsmToken::LessLess:
956    Kind = MCBinaryExpr::Shl;
957    return 4;
958  case AsmToken::GreaterGreater:
959    Kind = MCBinaryExpr::Shr;
960    return 4;
961
962    // High Intermediate Precedence: +, -
963  case AsmToken::Plus:
964    Kind = MCBinaryExpr::Add;
965    return 5;
966  case AsmToken::Minus:
967    Kind = MCBinaryExpr::Sub;
968    return 5;
969
970    // Highest Precedence: *, /, %
971  case AsmToken::Star:
972    Kind = MCBinaryExpr::Mul;
973    return 6;
974  case AsmToken::Slash:
975    Kind = MCBinaryExpr::Div;
976    return 6;
977  case AsmToken::Percent:
978    Kind = MCBinaryExpr::Mod;
979    return 6;
980  }
981}
982
983
984/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
985/// Res contains the LHS of the expression on input.
986bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
987                              SMLoc &EndLoc) {
988  while (1) {
989    MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
990    unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
991
992    // If the next token is lower precedence than we are allowed to eat, return
993    // successfully with what we ate already.
994    if (TokPrec < Precedence)
995      return false;
996
997    Lex();
998
999    // Eat the next primary expression.
1000    const MCExpr *RHS;
1001    if (ParsePrimaryExpr(RHS, EndLoc)) return true;
1002
1003    // If BinOp binds less tightly with RHS than the operator after RHS, let
1004    // the pending operator take RHS as its LHS.
1005    MCBinaryExpr::Opcode Dummy;
1006    unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
1007    if (TokPrec < NextTokPrec) {
1008      if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
1009    }
1010
1011    // Merge LHS and RHS according to operator.
1012    Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
1013  }
1014}
1015
1016
1017
1018
1019/// ParseStatement:
1020///   ::= EndOfStatement
1021///   ::= Label* Directive ...Operands... EndOfStatement
1022///   ::= Label* Identifier OperandList* EndOfStatement
1023bool AsmParser::ParseStatement() {
1024  if (Lexer.is(AsmToken::EndOfStatement)) {
1025    Out.AddBlankLine();
1026    Lex();
1027    return false;
1028  }
1029
1030  // Statements always start with an identifier or are a full line comment.
1031  AsmToken ID = getTok();
1032  SMLoc IDLoc = ID.getLoc();
1033  StringRef IDVal;
1034  int64_t LocalLabelVal = -1;
1035  // A full line comment is a '#' as the first token.
1036  if (Lexer.is(AsmToken::Hash))
1037    return ParseCppHashLineFilenameComment(IDLoc);
1038
1039  // Allow an integer followed by a ':' as a directional local label.
1040  if (Lexer.is(AsmToken::Integer)) {
1041    LocalLabelVal = getTok().getIntVal();
1042    if (LocalLabelVal < 0) {
1043      if (!TheCondState.Ignore)
1044        return TokError("unexpected token at start of statement");
1045      IDVal = "";
1046    }
1047    else {
1048      IDVal = getTok().getString();
1049      Lex(); // Consume the integer token to be used as an identifier token.
1050      if (Lexer.getKind() != AsmToken::Colon) {
1051        if (!TheCondState.Ignore)
1052          return TokError("unexpected token at start of statement");
1053      }
1054    }
1055
1056  } else if (Lexer.is(AsmToken::Dot)) {
1057    // Treat '.' as a valid identifier in this context.
1058    Lex();
1059    IDVal = ".";
1060
1061  } else if (ParseIdentifier(IDVal)) {
1062    if (!TheCondState.Ignore)
1063      return TokError("unexpected token at start of statement");
1064    IDVal = "";
1065  }
1066
1067
1068  // Handle conditional assembly here before checking for skipping.  We
1069  // have to do this so that .endif isn't skipped in a ".if 0" block for
1070  // example.
1071  if (IDVal == ".if")
1072    return ParseDirectiveIf(IDLoc);
1073  if (IDVal == ".ifb")
1074    return ParseDirectiveIfb(IDLoc, true);
1075  if (IDVal == ".ifnb")
1076    return ParseDirectiveIfb(IDLoc, false);
1077  if (IDVal == ".ifc")
1078    return ParseDirectiveIfc(IDLoc, true);
1079  if (IDVal == ".ifnc")
1080    return ParseDirectiveIfc(IDLoc, false);
1081  if (IDVal == ".ifdef")
1082    return ParseDirectiveIfdef(IDLoc, true);
1083  if (IDVal == ".ifndef" || IDVal == ".ifnotdef")
1084    return ParseDirectiveIfdef(IDLoc, false);
1085  if (IDVal == ".elseif")
1086    return ParseDirectiveElseIf(IDLoc);
1087  if (IDVal == ".else")
1088    return ParseDirectiveElse(IDLoc);
1089  if (IDVal == ".endif")
1090    return ParseDirectiveEndIf(IDLoc);
1091
1092  // If we are in a ".if 0" block, ignore this statement.
1093  if (TheCondState.Ignore) {
1094    EatToEndOfStatement();
1095    return false;
1096  }
1097
1098  // FIXME: Recurse on local labels?
1099
1100  // See what kind of statement we have.
1101  switch (Lexer.getKind()) {
1102  case AsmToken::Colon: {
1103    CheckForValidSection();
1104
1105    // identifier ':'   -> Label.
1106    Lex();
1107
1108    // Diagnose attempt to use '.' as a label.
1109    if (IDVal == ".")
1110      return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
1111
1112    // Diagnose attempt to use a variable as a label.
1113    //
1114    // FIXME: Diagnostics. Note the location of the definition as a label.
1115    // FIXME: This doesn't diagnose assignment to a symbol which has been
1116    // implicitly marked as external.
1117    MCSymbol *Sym;
1118    if (LocalLabelVal == -1)
1119      Sym = getContext().GetOrCreateSymbol(IDVal);
1120    else
1121      Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
1122    if (!Sym->isUndefined() || Sym->isVariable())
1123      return Error(IDLoc, "invalid symbol redefinition");
1124
1125    // Emit the label.
1126    Out.EmitLabel(Sym);
1127
1128    // If we are generating dwarf for assembly source files then gather the
1129    // info to make a dwarf label entry for this label if needed.
1130    if (getContext().getGenDwarfForAssembly())
1131      MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
1132                                 IDLoc);
1133
1134    // Consume any end of statement token, if present, to avoid spurious
1135    // AddBlankLine calls().
1136    if (Lexer.is(AsmToken::EndOfStatement)) {
1137      Lex();
1138      if (Lexer.is(AsmToken::Eof))
1139        return false;
1140    }
1141
1142    return ParseStatement();
1143  }
1144
1145  case AsmToken::Equal:
1146    // identifier '=' ... -> assignment statement
1147    Lex();
1148
1149    return ParseAssignment(IDVal, true);
1150
1151  default: // Normal instruction or directive.
1152    break;
1153  }
1154
1155  // If macros are enabled, check to see if this is a macro instantiation.
1156  if (MacrosEnabled)
1157    if (const Macro *M = MacroMap.lookup(IDVal))
1158      return HandleMacroEntry(IDVal, IDLoc, M);
1159
1160  // Otherwise, we have a normal instruction or directive.
1161  if (IDVal[0] == '.' && IDVal != ".") {
1162    // Assembler features
1163    if (IDVal == ".set" || IDVal == ".equ")
1164      return ParseDirectiveSet(IDVal, true);
1165    if (IDVal == ".equiv")
1166      return ParseDirectiveSet(IDVal, false);
1167
1168    // Data directives
1169
1170    if (IDVal == ".ascii")
1171      return ParseDirectiveAscii(IDVal, false);
1172    if (IDVal == ".asciz" || IDVal == ".string")
1173      return ParseDirectiveAscii(IDVal, true);
1174
1175    if (IDVal == ".byte")
1176      return ParseDirectiveValue(1);
1177    if (IDVal == ".short")
1178      return ParseDirectiveValue(2);
1179    if (IDVal == ".value")
1180      return ParseDirectiveValue(2);
1181    if (IDVal == ".2byte")
1182      return ParseDirectiveValue(2);
1183    if (IDVal == ".long")
1184      return ParseDirectiveValue(4);
1185    if (IDVal == ".int")
1186      return ParseDirectiveValue(4);
1187    if (IDVal == ".4byte")
1188      return ParseDirectiveValue(4);
1189    if (IDVal == ".quad")
1190      return ParseDirectiveValue(8);
1191    if (IDVal == ".8byte")
1192      return ParseDirectiveValue(8);
1193    if (IDVal == ".single" || IDVal == ".float")
1194      return ParseDirectiveRealValue(APFloat::IEEEsingle);
1195    if (IDVal == ".double")
1196      return ParseDirectiveRealValue(APFloat::IEEEdouble);
1197
1198    if (IDVal == ".align") {
1199      bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
1200      return ParseDirectiveAlign(IsPow2, /*ExprSize=*/1);
1201    }
1202    if (IDVal == ".align32") {
1203      bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
1204      return ParseDirectiveAlign(IsPow2, /*ExprSize=*/4);
1205    }
1206    if (IDVal == ".balign")
1207      return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
1208    if (IDVal == ".balignw")
1209      return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
1210    if (IDVal == ".balignl")
1211      return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
1212    if (IDVal == ".p2align")
1213      return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
1214    if (IDVal == ".p2alignw")
1215      return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
1216    if (IDVal == ".p2alignl")
1217      return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
1218
1219    if (IDVal == ".org")
1220      return ParseDirectiveOrg();
1221
1222    if (IDVal == ".fill")
1223      return ParseDirectiveFill();
1224    if (IDVal == ".space" || IDVal == ".skip")
1225      return ParseDirectiveSpace();
1226    if (IDVal == ".zero")
1227      return ParseDirectiveZero();
1228
1229    // Symbol attribute directives
1230
1231    if (IDVal == ".extern") {
1232      EatToEndOfStatement(); // .extern is the default, ignore it.
1233      return false;
1234    }
1235    if (IDVal == ".globl" || IDVal == ".global")
1236      return ParseDirectiveSymbolAttribute(MCSA_Global);
1237    if (IDVal == ".indirect_symbol")
1238      return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
1239    if (IDVal == ".lazy_reference")
1240      return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
1241    if (IDVal == ".no_dead_strip")
1242      return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
1243    if (IDVal == ".symbol_resolver")
1244      return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver);
1245    if (IDVal == ".private_extern")
1246      return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
1247    if (IDVal == ".reference")
1248      return ParseDirectiveSymbolAttribute(MCSA_Reference);
1249    if (IDVal == ".weak_definition")
1250      return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition);
1251    if (IDVal == ".weak_reference")
1252      return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
1253    if (IDVal == ".weak_def_can_be_hidden")
1254      return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
1255
1256    if (IDVal == ".comm" || IDVal == ".common")
1257      return ParseDirectiveComm(/*IsLocal=*/false);
1258    if (IDVal == ".lcomm")
1259      return ParseDirectiveComm(/*IsLocal=*/true);
1260
1261    if (IDVal == ".abort")
1262      return ParseDirectiveAbort();
1263    if (IDVal == ".include")
1264      return ParseDirectiveInclude();
1265    if (IDVal == ".incbin")
1266      return ParseDirectiveIncbin();
1267
1268    if (IDVal == ".code16" || IDVal == ".code16gcc")
1269      return TokError(Twine(IDVal) + " not supported yet");
1270
1271    if (IDVal == ".rept")
1272      return ParseDirectiveRept(IDLoc);
1273    if (IDVal == ".endr")
1274      return ParseDirectiveEndRept(IDLoc);
1275
1276    // Look up the handler in the handler table.
1277    std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
1278      DirectiveMap.lookup(IDVal);
1279    if (Handler.first)
1280      return (*Handler.second)(Handler.first, IDVal, IDLoc);
1281
1282    // Target hook for parsing target specific directives.
1283    if (!getTargetParser().ParseDirective(ID))
1284      return false;
1285
1286    return Error(IDLoc, "unknown directive");
1287  }
1288
1289  CheckForValidSection();
1290
1291  // Canonicalize the opcode to lower case.
1292  SmallString<128> Opcode;
1293  for (unsigned i = 0, e = IDVal.size(); i != e; ++i)
1294    Opcode.push_back(tolower(IDVal[i]));
1295
1296  SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
1297  bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc,
1298                                                     ParsedOperands);
1299
1300  // Dump the parsed representation, if requested.
1301  if (getShowParsedOperands()) {
1302    SmallString<256> Str;
1303    raw_svector_ostream OS(Str);
1304    OS << "parsed instruction: [";
1305    for (unsigned i = 0; i != ParsedOperands.size(); ++i) {
1306      if (i != 0)
1307        OS << ", ";
1308      ParsedOperands[i]->print(OS);
1309    }
1310    OS << "]";
1311
1312    PrintMessage(IDLoc, SourceMgr::DK_Note, OS.str());
1313  }
1314
1315  // If we are generating dwarf for assembly source files and the current
1316  // section is the initial text section then generate a .loc directive for
1317  // the instruction.
1318  if (!HadError && getContext().getGenDwarfForAssembly() &&
1319      getContext().getGenDwarfSection() == getStreamer().getCurrentSection() ) {
1320    getStreamer().EmitDwarfLocDirective(getContext().getGenDwarfFileNumber(),
1321                                        SrcMgr.FindLineNumber(IDLoc, CurBuffer),
1322                                        0, DWARF2_LINE_DEFAULT_IS_STMT ?
1323                                        DWARF2_FLAG_IS_STMT : 0, 0, 0,
1324                                        StringRef());
1325  }
1326
1327  // If parsing succeeded, match the instruction.
1328  if (!HadError)
1329    HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, ParsedOperands,
1330                                                         Out);
1331
1332  // Free any parsed operands.
1333  for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
1334    delete ParsedOperands[i];
1335
1336  // Don't skip the rest of the line, the instruction parser is responsible for
1337  // that.
1338  return false;
1339}
1340
1341/// EatToEndOfLine uses the Lexer to eat the characters to the end of the line
1342/// since they may not be able to be tokenized to get to the end of line token.
1343void AsmParser::EatToEndOfLine() {
1344  if (!Lexer.is(AsmToken::EndOfStatement))
1345    Lexer.LexUntilEndOfLine();
1346 // Eat EOL.
1347 Lex();
1348}
1349
1350/// ParseCppHashLineFilenameComment as this:
1351///   ::= # number "filename"
1352/// or just as a full line comment if it doesn't have a number and a string.
1353bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) {
1354  Lex(); // Eat the hash token.
1355
1356  if (getLexer().isNot(AsmToken::Integer)) {
1357    // Consume the line since in cases it is not a well-formed line directive,
1358    // as if were simply a full line comment.
1359    EatToEndOfLine();
1360    return false;
1361  }
1362
1363  int64_t LineNumber = getTok().getIntVal();
1364  Lex();
1365
1366  if (getLexer().isNot(AsmToken::String)) {
1367    EatToEndOfLine();
1368    return false;
1369  }
1370
1371  StringRef Filename = getTok().getString();
1372  // Get rid of the enclosing quotes.
1373  Filename = Filename.substr(1, Filename.size()-2);
1374
1375  // Save the SMLoc, Filename and LineNumber for later use by diagnostics.
1376  CppHashLoc = L;
1377  CppHashFilename = Filename;
1378  CppHashLineNumber = LineNumber;
1379
1380  // Ignore any trailing characters, they're just comment.
1381  EatToEndOfLine();
1382  return false;
1383}
1384
1385/// DiagHandler - will use the the last parsed cpp hash line filename comment
1386/// for the Filename and LineNo if any in the diagnostic.
1387void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
1388  const AsmParser *Parser = static_cast<const AsmParser*>(Context);
1389  raw_ostream &OS = errs();
1390
1391  const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
1392  const SMLoc &DiagLoc = Diag.getLoc();
1393  int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
1394  int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc);
1395
1396  // Like SourceMgr::PrintMessage() we need to print the include stack if any
1397  // before printing the message.
1398  int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
1399  if (!Parser->SavedDiagHandler && DiagCurBuffer > 0) {
1400     SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
1401     DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
1402  }
1403
1404  // If we have not parsed a cpp hash line filename comment or the source
1405  // manager changed or buffer changed (like in a nested include) then just
1406  // print the normal diagnostic using its Filename and LineNo.
1407  if (!Parser->CppHashLineNumber ||
1408      &DiagSrcMgr != &Parser->SrcMgr ||
1409      DiagBuf != CppHashBuf) {
1410    if (Parser->SavedDiagHandler)
1411      Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
1412    else
1413      Diag.print(0, OS);
1414    return;
1415  }
1416
1417  // Use the CppHashFilename and calculate a line number based on the
1418  // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for
1419  // the diagnostic.
1420  const std::string Filename = Parser->CppHashFilename;
1421
1422  int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
1423  int CppHashLocLineNo =
1424      Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf);
1425  int LineNo = Parser->CppHashLineNumber - 1 +
1426               (DiagLocLineNo - CppHashLocLineNo);
1427
1428  SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(),
1429                       Filename, LineNo, Diag.getColumnNo(),
1430                       Diag.getKind(), Diag.getMessage(),
1431                       Diag.getLineContents(), Diag.getRanges());
1432
1433  if (Parser->SavedDiagHandler)
1434    Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
1435  else
1436    NewDiag.print(0, OS);
1437}
1438
1439bool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body,
1440                            const std::vector<StringRef> &Parameters,
1441                            const std::vector<std::vector<AsmToken> > &A,
1442                            const SMLoc &L) {
1443  raw_svector_ostream OS(Buf);
1444  unsigned NParameters = Parameters.size();
1445  if (NParameters != 0 && NParameters != A.size())
1446    return Error(L, "Wrong number of arguments");
1447
1448  while (!Body.empty()) {
1449    // Scan for the next substitution.
1450    std::size_t End = Body.size(), Pos = 0;
1451    for (; Pos != End; ++Pos) {
1452      // Check for a substitution or escape.
1453      if (!NParameters) {
1454        // This macro has no parameters, look for $0, $1, etc.
1455        if (Body[Pos] != '$' || Pos + 1 == End)
1456          continue;
1457
1458        char Next = Body[Pos + 1];
1459        if (Next == '$' || Next == 'n' || isdigit(Next))
1460          break;
1461      } else {
1462        // This macro has parameters, look for \foo, \bar, etc.
1463        if (Body[Pos] == '\\' && Pos + 1 != End)
1464          break;
1465      }
1466    }
1467
1468    // Add the prefix.
1469    OS << Body.slice(0, Pos);
1470
1471    // Check if we reached the end.
1472    if (Pos == End)
1473      break;
1474
1475    if (!NParameters) {
1476      switch (Body[Pos+1]) {
1477        // $$ => $
1478      case '$':
1479        OS << '$';
1480        break;
1481
1482        // $n => number of arguments
1483      case 'n':
1484        OS << A.size();
1485        break;
1486
1487        // $[0-9] => argument
1488      default: {
1489        // Missing arguments are ignored.
1490        unsigned Index = Body[Pos+1] - '0';
1491        if (Index >= A.size())
1492          break;
1493
1494        // Otherwise substitute with the token values, with spaces eliminated.
1495        for (std::vector<AsmToken>::const_iterator it = A[Index].begin(),
1496               ie = A[Index].end(); it != ie; ++it)
1497          OS << it->getString();
1498        break;
1499      }
1500      }
1501      Pos += 2;
1502    } else {
1503      unsigned I = Pos + 1;
1504      while (isalnum(Body[I]) && I + 1 != End)
1505        ++I;
1506
1507      const char *Begin = Body.data() + Pos +1;
1508      StringRef Argument(Begin, I - (Pos +1));
1509      unsigned Index = 0;
1510      for (; Index < NParameters; ++Index)
1511        if (Parameters[Index] == Argument)
1512          break;
1513
1514      // FIXME: We should error at the macro definition.
1515      if (Index == NParameters)
1516        return Error(L, "Parameter not found");
1517
1518      for (std::vector<AsmToken>::const_iterator it = A[Index].begin(),
1519             ie = A[Index].end(); it != ie; ++it)
1520        OS << it->getString();
1521
1522      Pos += 1 + Argument.size();
1523    }
1524    // Update the scan point.
1525    Body = Body.substr(Pos);
1526  }
1527
1528  // We include the .endmacro in the buffer as our queue to exit the macro
1529  // instantiation.
1530  OS << ".endmacro\n";
1531  return false;
1532}
1533
1534MacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL,
1535                                       MemoryBuffer *I)
1536  : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitLoc(EL)
1537{
1538}
1539
1540bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc,
1541                                 const Macro *M) {
1542  // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
1543  // this, although we should protect against infinite loops.
1544  if (ActiveMacros.size() == 20)
1545    return TokError("macros cannot be nested more than 20 levels deep");
1546
1547  // Parse the macro instantiation arguments.
1548  std::vector<std::vector<AsmToken> > MacroArguments;
1549  MacroArguments.push_back(std::vector<AsmToken>());
1550  unsigned ParenLevel = 0;
1551  for (;;) {
1552    if (Lexer.is(AsmToken::Eof))
1553      return TokError("unexpected token in macro instantiation");
1554    if (Lexer.is(AsmToken::EndOfStatement))
1555      break;
1556
1557    // If we aren't inside parentheses and this is a comma, start a new token
1558    // list.
1559    if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) {
1560      MacroArguments.push_back(std::vector<AsmToken>());
1561    } else {
1562      // Adjust the current parentheses level.
1563      if (Lexer.is(AsmToken::LParen))
1564        ++ParenLevel;
1565      else if (Lexer.is(AsmToken::RParen) && ParenLevel)
1566        --ParenLevel;
1567
1568      // Append the token to the current argument list.
1569      MacroArguments.back().push_back(getTok());
1570    }
1571    Lex();
1572  }
1573  // If the last argument didn't end up with any tokens, it's not a real
1574  // argument and we should remove it from the list. This happens with either
1575  // a tailing comma or an empty argument list.
1576  if (MacroArguments.back().empty())
1577    MacroArguments.pop_back();
1578
1579  // Macro instantiation is lexical, unfortunately. We construct a new buffer
1580  // to hold the macro body with substitutions.
1581  SmallString<256> Buf;
1582  StringRef Body = M->Body;
1583
1584  if (expandMacro(Buf, Body, M->Parameters, MacroArguments, getTok().getLoc()))
1585    return true;
1586
1587  MemoryBuffer *Instantiation =
1588    MemoryBuffer::getMemBufferCopy(Buf.str(), "<instantiation>");
1589
1590  // Create the macro instantiation object and add to the current macro
1591  // instantiation stack.
1592  MacroInstantiation *MI = new MacroInstantiation(M, NameLoc,
1593                                                  getTok().getLoc(),
1594                                                  Instantiation);
1595  ActiveMacros.push_back(MI);
1596
1597  // Jump to the macro instantiation and prime the lexer.
1598  CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc());
1599  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
1600  Lex();
1601
1602  return false;
1603}
1604
1605void AsmParser::HandleMacroExit() {
1606  // Jump to the EndOfStatement we should return to, and consume it.
1607  JumpToLoc(ActiveMacros.back()->ExitLoc);
1608  Lex();
1609
1610  // Pop the instantiation entry.
1611  delete ActiveMacros.back();
1612  ActiveMacros.pop_back();
1613}
1614
1615static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) {
1616  switch (Value->getKind()) {
1617  case MCExpr::Binary: {
1618    const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Value);
1619    return IsUsedIn(Sym, BE->getLHS()) || IsUsedIn(Sym, BE->getRHS());
1620    break;
1621  }
1622  case MCExpr::Target:
1623  case MCExpr::Constant:
1624    return false;
1625  case MCExpr::SymbolRef: {
1626    const MCSymbol &S = static_cast<const MCSymbolRefExpr*>(Value)->getSymbol();
1627    if (S.isVariable())
1628      return IsUsedIn(Sym, S.getVariableValue());
1629    return &S == Sym;
1630  }
1631  case MCExpr::Unary:
1632    return IsUsedIn(Sym, static_cast<const MCUnaryExpr*>(Value)->getSubExpr());
1633  }
1634
1635  llvm_unreachable("Unknown expr kind!");
1636}
1637
1638bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
1639  // FIXME: Use better location, we should use proper tokens.
1640  SMLoc EqualLoc = Lexer.getLoc();
1641
1642  const MCExpr *Value;
1643  if (ParseExpression(Value))
1644    return true;
1645
1646  // Note: we don't count b as used in "a = b". This is to allow
1647  // a = b
1648  // b = c
1649
1650  if (Lexer.isNot(AsmToken::EndOfStatement))
1651    return TokError("unexpected token in assignment");
1652
1653  // Error on assignment to '.'.
1654  if (Name == ".") {
1655    return Error(EqualLoc, ("assignment to pseudo-symbol '.' is unsupported "
1656                            "(use '.space' or '.org').)"));
1657  }
1658
1659  // Eat the end of statement marker.
1660  Lex();
1661
1662  // Validate that the LHS is allowed to be a variable (either it has not been
1663  // used as a symbol, or it is an absolute symbol).
1664  MCSymbol *Sym = getContext().LookupSymbol(Name);
1665  if (Sym) {
1666    // Diagnose assignment to a label.
1667    //
1668    // FIXME: Diagnostics. Note the location of the definition as a label.
1669    // FIXME: Diagnose assignment to protected identifier (e.g., register name).
1670    if (IsUsedIn(Sym, Value))
1671      return Error(EqualLoc, "Recursive use of '" + Name + "'");
1672    else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
1673      ; // Allow redefinitions of undefined symbols only used in directives.
1674    else if (Sym->isVariable() && !Sym->isUsed() && allow_redef)
1675      ; // Allow redefinitions of variables that haven't yet been used.
1676    else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef))
1677      return Error(EqualLoc, "redefinition of '" + Name + "'");
1678    else if (!Sym->isVariable())
1679      return Error(EqualLoc, "invalid assignment to '" + Name + "'");
1680    else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
1681      return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
1682                   Name + "'");
1683
1684    // Don't count these checks as uses.
1685    Sym->setUsed(false);
1686  } else
1687    Sym = getContext().GetOrCreateSymbol(Name);
1688
1689  // FIXME: Handle '.'.
1690
1691  // Do the assignment.
1692  Out.EmitAssignment(Sym, Value);
1693
1694  return false;
1695}
1696
1697/// ParseIdentifier:
1698///   ::= identifier
1699///   ::= string
1700bool AsmParser::ParseIdentifier(StringRef &Res) {
1701  // The assembler has relaxed rules for accepting identifiers, in particular we
1702  // allow things like '.globl $foo', which would normally be separate
1703  // tokens. At this level, we have already lexed so we cannot (currently)
1704  // handle this as a context dependent token, instead we detect adjacent tokens
1705  // and return the combined identifier.
1706  if (Lexer.is(AsmToken::Dollar)) {
1707    SMLoc DollarLoc = getLexer().getLoc();
1708
1709    // Consume the dollar sign, and check for a following identifier.
1710    Lex();
1711    if (Lexer.isNot(AsmToken::Identifier))
1712      return true;
1713
1714    // We have a '$' followed by an identifier, make sure they are adjacent.
1715    if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1716      return true;
1717
1718    // Construct the joined identifier and consume the token.
1719    Res = StringRef(DollarLoc.getPointer(),
1720                    getTok().getIdentifier().size() + 1);
1721    Lex();
1722    return false;
1723  }
1724
1725  if (Lexer.isNot(AsmToken::Identifier) &&
1726      Lexer.isNot(AsmToken::String))
1727    return true;
1728
1729  Res = getTok().getIdentifier();
1730
1731  Lex(); // Consume the identifier token.
1732
1733  return false;
1734}
1735
1736/// ParseDirectiveSet:
1737///   ::= .equ identifier ',' expression
1738///   ::= .equiv identifier ',' expression
1739///   ::= .set identifier ',' expression
1740bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) {
1741  StringRef Name;
1742
1743  if (ParseIdentifier(Name))
1744    return TokError("expected identifier after '" + Twine(IDVal) + "'");
1745
1746  if (getLexer().isNot(AsmToken::Comma))
1747    return TokError("unexpected token in '" + Twine(IDVal) + "'");
1748  Lex();
1749
1750  return ParseAssignment(Name, allow_redef);
1751}
1752
1753bool AsmParser::ParseEscapedString(std::string &Data) {
1754  assert(getLexer().is(AsmToken::String) && "Unexpected current token!");
1755
1756  Data = "";
1757  StringRef Str = getTok().getStringContents();
1758  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
1759    if (Str[i] != '\\') {
1760      Data += Str[i];
1761      continue;
1762    }
1763
1764    // Recognize escaped characters. Note that this escape semantics currently
1765    // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
1766    ++i;
1767    if (i == e)
1768      return TokError("unexpected backslash at end of string");
1769
1770    // Recognize octal sequences.
1771    if ((unsigned) (Str[i] - '0') <= 7) {
1772      // Consume up to three octal characters.
1773      unsigned Value = Str[i] - '0';
1774
1775      if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1776        ++i;
1777        Value = Value * 8 + (Str[i] - '0');
1778
1779        if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1780          ++i;
1781          Value = Value * 8 + (Str[i] - '0');
1782        }
1783      }
1784
1785      if (Value > 255)
1786        return TokError("invalid octal escape sequence (out of range)");
1787
1788      Data += (unsigned char) Value;
1789      continue;
1790    }
1791
1792    // Otherwise recognize individual escapes.
1793    switch (Str[i]) {
1794    default:
1795      // Just reject invalid escape sequences for now.
1796      return TokError("invalid escape sequence (unrecognized character)");
1797
1798    case 'b': Data += '\b'; break;
1799    case 'f': Data += '\f'; break;
1800    case 'n': Data += '\n'; break;
1801    case 'r': Data += '\r'; break;
1802    case 't': Data += '\t'; break;
1803    case '"': Data += '"'; break;
1804    case '\\': Data += '\\'; break;
1805    }
1806  }
1807
1808  return false;
1809}
1810
1811/// ParseDirectiveAscii:
1812///   ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
1813bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
1814  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1815    CheckForValidSection();
1816
1817    for (;;) {
1818      if (getLexer().isNot(AsmToken::String))
1819        return TokError("expected string in '" + Twine(IDVal) + "' directive");
1820
1821      std::string Data;
1822      if (ParseEscapedString(Data))
1823        return true;
1824
1825      getStreamer().EmitBytes(Data, DEFAULT_ADDRSPACE);
1826      if (ZeroTerminated)
1827        getStreamer().EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
1828
1829      Lex();
1830
1831      if (getLexer().is(AsmToken::EndOfStatement))
1832        break;
1833
1834      if (getLexer().isNot(AsmToken::Comma))
1835        return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
1836      Lex();
1837    }
1838  }
1839
1840  Lex();
1841  return false;
1842}
1843
1844/// ParseDirectiveValue
1845///  ::= (.byte | .short | ... ) [ expression (, expression)* ]
1846bool AsmParser::ParseDirectiveValue(unsigned Size) {
1847  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1848    CheckForValidSection();
1849
1850    for (;;) {
1851      const MCExpr *Value;
1852      SMLoc ExprLoc = getLexer().getLoc();
1853      if (ParseExpression(Value))
1854        return true;
1855
1856      // Special case constant expressions to match code generator.
1857      if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
1858        assert(Size <= 8 && "Invalid size");
1859        uint64_t IntValue = MCE->getValue();
1860        if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
1861          return Error(ExprLoc, "literal value out of range for directive");
1862        getStreamer().EmitIntValue(IntValue, Size, DEFAULT_ADDRSPACE);
1863      } else
1864        getStreamer().EmitValue(Value, Size, DEFAULT_ADDRSPACE);
1865
1866      if (getLexer().is(AsmToken::EndOfStatement))
1867        break;
1868
1869      // FIXME: Improve diagnostic.
1870      if (getLexer().isNot(AsmToken::Comma))
1871        return TokError("unexpected token in directive");
1872      Lex();
1873    }
1874  }
1875
1876  Lex();
1877  return false;
1878}
1879
1880/// ParseDirectiveRealValue
1881///  ::= (.single | .double) [ expression (, expression)* ]
1882bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) {
1883  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1884    CheckForValidSection();
1885
1886    for (;;) {
1887      // We don't truly support arithmetic on floating point expressions, so we
1888      // have to manually parse unary prefixes.
1889      bool IsNeg = false;
1890      if (getLexer().is(AsmToken::Minus)) {
1891        Lex();
1892        IsNeg = true;
1893      } else if (getLexer().is(AsmToken::Plus))
1894        Lex();
1895
1896      if (getLexer().isNot(AsmToken::Integer) &&
1897          getLexer().isNot(AsmToken::Real) &&
1898          getLexer().isNot(AsmToken::Identifier))
1899        return TokError("unexpected token in directive");
1900
1901      // Convert to an APFloat.
1902      APFloat Value(Semantics);
1903      StringRef IDVal = getTok().getString();
1904      if (getLexer().is(AsmToken::Identifier)) {
1905        if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf"))
1906          Value = APFloat::getInf(Semantics);
1907        else if (!IDVal.compare_lower("nan"))
1908          Value = APFloat::getNaN(Semantics, false, ~0);
1909        else
1910          return TokError("invalid floating point literal");
1911      } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
1912          APFloat::opInvalidOp)
1913        return TokError("invalid floating point literal");
1914      if (IsNeg)
1915        Value.changeSign();
1916
1917      // Consume the numeric token.
1918      Lex();
1919
1920      // Emit the value as an integer.
1921      APInt AsInt = Value.bitcastToAPInt();
1922      getStreamer().EmitIntValue(AsInt.getLimitedValue(),
1923                                 AsInt.getBitWidth() / 8, DEFAULT_ADDRSPACE);
1924
1925      if (getLexer().is(AsmToken::EndOfStatement))
1926        break;
1927
1928      if (getLexer().isNot(AsmToken::Comma))
1929        return TokError("unexpected token in directive");
1930      Lex();
1931    }
1932  }
1933
1934  Lex();
1935  return false;
1936}
1937
1938/// ParseDirectiveSpace
1939///  ::= .space expression [ , expression ]
1940bool AsmParser::ParseDirectiveSpace() {
1941  CheckForValidSection();
1942
1943  int64_t NumBytes;
1944  if (ParseAbsoluteExpression(NumBytes))
1945    return true;
1946
1947  int64_t FillExpr = 0;
1948  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1949    if (getLexer().isNot(AsmToken::Comma))
1950      return TokError("unexpected token in '.space' directive");
1951    Lex();
1952
1953    if (ParseAbsoluteExpression(FillExpr))
1954      return true;
1955
1956    if (getLexer().isNot(AsmToken::EndOfStatement))
1957      return TokError("unexpected token in '.space' directive");
1958  }
1959
1960  Lex();
1961
1962  if (NumBytes <= 0)
1963    return TokError("invalid number of bytes in '.space' directive");
1964
1965  // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
1966  getStreamer().EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
1967
1968  return false;
1969}
1970
1971/// ParseDirectiveZero
1972///  ::= .zero expression
1973bool AsmParser::ParseDirectiveZero() {
1974  CheckForValidSection();
1975
1976  int64_t NumBytes;
1977  if (ParseAbsoluteExpression(NumBytes))
1978    return true;
1979
1980  int64_t Val = 0;
1981  if (getLexer().is(AsmToken::Comma)) {
1982    Lex();
1983    if (ParseAbsoluteExpression(Val))
1984      return true;
1985  }
1986
1987  if (getLexer().isNot(AsmToken::EndOfStatement))
1988    return TokError("unexpected token in '.zero' directive");
1989
1990  Lex();
1991
1992  getStreamer().EmitFill(NumBytes, Val, DEFAULT_ADDRSPACE);
1993
1994  return false;
1995}
1996
1997/// ParseDirectiveFill
1998///  ::= .fill expression , expression , expression
1999bool AsmParser::ParseDirectiveFill() {
2000  CheckForValidSection();
2001
2002  int64_t NumValues;
2003  if (ParseAbsoluteExpression(NumValues))
2004    return true;
2005
2006  if (getLexer().isNot(AsmToken::Comma))
2007    return TokError("unexpected token in '.fill' directive");
2008  Lex();
2009
2010  int64_t FillSize;
2011  if (ParseAbsoluteExpression(FillSize))
2012    return true;
2013
2014  if (getLexer().isNot(AsmToken::Comma))
2015    return TokError("unexpected token in '.fill' directive");
2016  Lex();
2017
2018  int64_t FillExpr;
2019  if (ParseAbsoluteExpression(FillExpr))
2020    return true;
2021
2022  if (getLexer().isNot(AsmToken::EndOfStatement))
2023    return TokError("unexpected token in '.fill' directive");
2024
2025  Lex();
2026
2027  if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
2028    return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
2029
2030  for (uint64_t i = 0, e = NumValues; i != e; ++i)
2031    getStreamer().EmitIntValue(FillExpr, FillSize, DEFAULT_ADDRSPACE);
2032
2033  return false;
2034}
2035
2036/// ParseDirectiveOrg
2037///  ::= .org expression [ , expression ]
2038bool AsmParser::ParseDirectiveOrg() {
2039  CheckForValidSection();
2040
2041  const MCExpr *Offset;
2042  SMLoc Loc = getTok().getLoc();
2043  if (ParseExpression(Offset))
2044    return true;
2045
2046  // Parse optional fill expression.
2047  int64_t FillExpr = 0;
2048  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2049    if (getLexer().isNot(AsmToken::Comma))
2050      return TokError("unexpected token in '.org' directive");
2051    Lex();
2052
2053    if (ParseAbsoluteExpression(FillExpr))
2054      return true;
2055
2056    if (getLexer().isNot(AsmToken::EndOfStatement))
2057      return TokError("unexpected token in '.org' directive");
2058  }
2059
2060  Lex();
2061
2062  // Only limited forms of relocatable expressions are accepted here, it
2063  // has to be relative to the current section. The streamer will return
2064  // 'true' if the expression wasn't evaluatable.
2065  if (getStreamer().EmitValueToOffset(Offset, FillExpr))
2066    return Error(Loc, "expected assembly-time absolute expression");
2067
2068  return false;
2069}
2070
2071/// ParseDirectiveAlign
2072///  ::= {.align, ...} expression [ , expression [ , expression ]]
2073bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
2074  CheckForValidSection();
2075
2076  SMLoc AlignmentLoc = getLexer().getLoc();
2077  int64_t Alignment;
2078  if (ParseAbsoluteExpression(Alignment))
2079    return true;
2080
2081  SMLoc MaxBytesLoc;
2082  bool HasFillExpr = false;
2083  int64_t FillExpr = 0;
2084  int64_t MaxBytesToFill = 0;
2085  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2086    if (getLexer().isNot(AsmToken::Comma))
2087      return TokError("unexpected token in directive");
2088    Lex();
2089
2090    // The fill expression can be omitted while specifying a maximum number of
2091    // alignment bytes, e.g:
2092    //  .align 3,,4
2093    if (getLexer().isNot(AsmToken::Comma)) {
2094      HasFillExpr = true;
2095      if (ParseAbsoluteExpression(FillExpr))
2096        return true;
2097    }
2098
2099    if (getLexer().isNot(AsmToken::EndOfStatement)) {
2100      if (getLexer().isNot(AsmToken::Comma))
2101        return TokError("unexpected token in directive");
2102      Lex();
2103
2104      MaxBytesLoc = getLexer().getLoc();
2105      if (ParseAbsoluteExpression(MaxBytesToFill))
2106        return true;
2107
2108      if (getLexer().isNot(AsmToken::EndOfStatement))
2109        return TokError("unexpected token in directive");
2110    }
2111  }
2112
2113  Lex();
2114
2115  if (!HasFillExpr)
2116    FillExpr = 0;
2117
2118  // Compute alignment in bytes.
2119  if (IsPow2) {
2120    // FIXME: Diagnose overflow.
2121    if (Alignment >= 32) {
2122      Error(AlignmentLoc, "invalid alignment value");
2123      Alignment = 31;
2124    }
2125
2126    Alignment = 1ULL << Alignment;
2127  }
2128
2129  // Diagnose non-sensical max bytes to align.
2130  if (MaxBytesLoc.isValid()) {
2131    if (MaxBytesToFill < 1) {
2132      Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
2133            "many bytes, ignoring maximum bytes expression");
2134      MaxBytesToFill = 0;
2135    }
2136
2137    if (MaxBytesToFill >= Alignment) {
2138      Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
2139              "has no effect");
2140      MaxBytesToFill = 0;
2141    }
2142  }
2143
2144  // Check whether we should use optimal code alignment for this .align
2145  // directive.
2146  bool UseCodeAlign = getStreamer().getCurrentSection()->UseCodeAlign();
2147  if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
2148      ValueSize == 1 && UseCodeAlign) {
2149    getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill);
2150  } else {
2151    // FIXME: Target specific behavior about how the "extra" bytes are filled.
2152    getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize,
2153                                       MaxBytesToFill);
2154  }
2155
2156  return false;
2157}
2158
2159/// ParseDirectiveSymbolAttribute
2160///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
2161bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
2162  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2163    for (;;) {
2164      StringRef Name;
2165      SMLoc Loc = getTok().getLoc();
2166
2167      if (ParseIdentifier(Name))
2168        return Error(Loc, "expected identifier in directive");
2169
2170      MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2171
2172      // Assembler local symbols don't make any sense here. Complain loudly.
2173      if (Sym->isTemporary())
2174        return Error(Loc, "non-local symbol required in directive");
2175
2176      getStreamer().EmitSymbolAttribute(Sym, Attr);
2177
2178      if (getLexer().is(AsmToken::EndOfStatement))
2179        break;
2180
2181      if (getLexer().isNot(AsmToken::Comma))
2182        return TokError("unexpected token in directive");
2183      Lex();
2184    }
2185  }
2186
2187  Lex();
2188  return false;
2189}
2190
2191/// ParseDirectiveComm
2192///  ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
2193bool AsmParser::ParseDirectiveComm(bool IsLocal) {
2194  CheckForValidSection();
2195
2196  SMLoc IDLoc = getLexer().getLoc();
2197  StringRef Name;
2198  if (ParseIdentifier(Name))
2199    return TokError("expected identifier in directive");
2200
2201  // Handle the identifier as the key symbol.
2202  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2203
2204  if (getLexer().isNot(AsmToken::Comma))
2205    return TokError("unexpected token in directive");
2206  Lex();
2207
2208  int64_t Size;
2209  SMLoc SizeLoc = getLexer().getLoc();
2210  if (ParseAbsoluteExpression(Size))
2211    return true;
2212
2213  int64_t Pow2Alignment = 0;
2214  SMLoc Pow2AlignmentLoc;
2215  if (getLexer().is(AsmToken::Comma)) {
2216    Lex();
2217    Pow2AlignmentLoc = getLexer().getLoc();
2218    if (ParseAbsoluteExpression(Pow2Alignment))
2219      return true;
2220
2221    // If this target takes alignments in bytes (not log) validate and convert.
2222    if (Lexer.getMAI().getAlignmentIsInBytes()) {
2223      if (!isPowerOf2_64(Pow2Alignment))
2224        return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
2225      Pow2Alignment = Log2_64(Pow2Alignment);
2226    }
2227  }
2228
2229  if (getLexer().isNot(AsmToken::EndOfStatement))
2230    return TokError("unexpected token in '.comm' or '.lcomm' directive");
2231
2232  Lex();
2233
2234  // NOTE: a size of zero for a .comm should create a undefined symbol
2235  // but a size of .lcomm creates a bss symbol of size zero.
2236  if (Size < 0)
2237    return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
2238                 "be less than zero");
2239
2240  // NOTE: The alignment in the directive is a power of 2 value, the assembler
2241  // may internally end up wanting an alignment in bytes.
2242  // FIXME: Diagnose overflow.
2243  if (Pow2Alignment < 0)
2244    return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
2245                 "alignment, can't be less than zero");
2246
2247  if (!Sym->isUndefined())
2248    return Error(IDLoc, "invalid symbol redefinition");
2249
2250  // '.lcomm' is equivalent to '.zerofill'.
2251  // Create the Symbol as a common or local common with Size and Pow2Alignment
2252  if (IsLocal) {
2253    getStreamer().EmitZerofill(Ctx.getMachOSection(
2254                                 "__DATA", "__bss", MCSectionMachO::S_ZEROFILL,
2255                                 0, SectionKind::getBSS()),
2256                               Sym, Size, 1 << Pow2Alignment);
2257    return false;
2258  }
2259
2260  getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
2261  return false;
2262}
2263
2264/// ParseDirectiveAbort
2265///  ::= .abort [... message ...]
2266bool AsmParser::ParseDirectiveAbort() {
2267  // FIXME: Use loc from directive.
2268  SMLoc Loc = getLexer().getLoc();
2269
2270  StringRef Str = ParseStringToEndOfStatement();
2271  if (getLexer().isNot(AsmToken::EndOfStatement))
2272    return TokError("unexpected token in '.abort' directive");
2273
2274  Lex();
2275
2276  if (Str.empty())
2277    Error(Loc, ".abort detected. Assembly stopping.");
2278  else
2279    Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
2280  // FIXME: Actually abort assembly here.
2281
2282  return false;
2283}
2284
2285/// ParseDirectiveInclude
2286///  ::= .include "filename"
2287bool AsmParser::ParseDirectiveInclude() {
2288  if (getLexer().isNot(AsmToken::String))
2289    return TokError("expected string in '.include' directive");
2290
2291  std::string Filename = getTok().getString();
2292  SMLoc IncludeLoc = getLexer().getLoc();
2293  Lex();
2294
2295  if (getLexer().isNot(AsmToken::EndOfStatement))
2296    return TokError("unexpected token in '.include' directive");
2297
2298  // Strip the quotes.
2299  Filename = Filename.substr(1, Filename.size()-2);
2300
2301  // Attempt to switch the lexer to the included file before consuming the end
2302  // of statement to avoid losing it when we switch.
2303  if (EnterIncludeFile(Filename)) {
2304    Error(IncludeLoc, "Could not find include file '" + Filename + "'");
2305    return true;
2306  }
2307
2308  return false;
2309}
2310
2311/// ParseDirectiveIncbin
2312///  ::= .incbin "filename"
2313bool AsmParser::ParseDirectiveIncbin() {
2314  if (getLexer().isNot(AsmToken::String))
2315    return TokError("expected string in '.incbin' directive");
2316
2317  std::string Filename = getTok().getString();
2318  SMLoc IncbinLoc = getLexer().getLoc();
2319  Lex();
2320
2321  if (getLexer().isNot(AsmToken::EndOfStatement))
2322    return TokError("unexpected token in '.incbin' directive");
2323
2324  // Strip the quotes.
2325  Filename = Filename.substr(1, Filename.size()-2);
2326
2327  // Attempt to process the included file.
2328  if (ProcessIncbinFile(Filename)) {
2329    Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
2330    return true;
2331  }
2332
2333  return false;
2334}
2335
2336/// ParseDirectiveIf
2337/// ::= .if expression
2338bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
2339  TheCondStack.push_back(TheCondState);
2340  TheCondState.TheCond = AsmCond::IfCond;
2341  if (TheCondState.Ignore) {
2342    EatToEndOfStatement();
2343  } else {
2344    int64_t ExprValue;
2345    if (ParseAbsoluteExpression(ExprValue))
2346      return true;
2347
2348    if (getLexer().isNot(AsmToken::EndOfStatement))
2349      return TokError("unexpected token in '.if' directive");
2350
2351    Lex();
2352
2353    TheCondState.CondMet = ExprValue;
2354    TheCondState.Ignore = !TheCondState.CondMet;
2355  }
2356
2357  return false;
2358}
2359
2360/// ParseDirectiveIfb
2361/// ::= .ifb string
2362bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
2363  TheCondStack.push_back(TheCondState);
2364  TheCondState.TheCond = AsmCond::IfCond;
2365
2366  if (TheCondState.Ignore) {
2367    EatToEndOfStatement();
2368  } else {
2369    StringRef Str = ParseStringToEndOfStatement();
2370
2371    if (getLexer().isNot(AsmToken::EndOfStatement))
2372      return TokError("unexpected token in '.ifb' directive");
2373
2374    Lex();
2375
2376    TheCondState.CondMet = ExpectBlank == Str.empty();
2377    TheCondState.Ignore = !TheCondState.CondMet;
2378  }
2379
2380  return false;
2381}
2382
2383/// ParseDirectiveIfc
2384/// ::= .ifc string1, string2
2385bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
2386  TheCondStack.push_back(TheCondState);
2387  TheCondState.TheCond = AsmCond::IfCond;
2388
2389  if (TheCondState.Ignore) {
2390    EatToEndOfStatement();
2391  } else {
2392    StringRef Str1 = ParseStringToComma();
2393
2394    if (getLexer().isNot(AsmToken::Comma))
2395      return TokError("unexpected token in '.ifc' directive");
2396
2397    Lex();
2398
2399    StringRef Str2 = ParseStringToEndOfStatement();
2400
2401    if (getLexer().isNot(AsmToken::EndOfStatement))
2402      return TokError("unexpected token in '.ifc' directive");
2403
2404    Lex();
2405
2406    TheCondState.CondMet = ExpectEqual == (Str1 == Str2);
2407    TheCondState.Ignore = !TheCondState.CondMet;
2408  }
2409
2410  return false;
2411}
2412
2413/// ParseDirectiveIfdef
2414/// ::= .ifdef symbol
2415bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
2416  StringRef Name;
2417  TheCondStack.push_back(TheCondState);
2418  TheCondState.TheCond = AsmCond::IfCond;
2419
2420  if (TheCondState.Ignore) {
2421    EatToEndOfStatement();
2422  } else {
2423    if (ParseIdentifier(Name))
2424      return TokError("expected identifier after '.ifdef'");
2425
2426    Lex();
2427
2428    MCSymbol *Sym = getContext().LookupSymbol(Name);
2429
2430    if (expect_defined)
2431      TheCondState.CondMet = (Sym != NULL && !Sym->isUndefined());
2432    else
2433      TheCondState.CondMet = (Sym == NULL || Sym->isUndefined());
2434    TheCondState.Ignore = !TheCondState.CondMet;
2435  }
2436
2437  return false;
2438}
2439
2440/// ParseDirectiveElseIf
2441/// ::= .elseif expression
2442bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
2443  if (TheCondState.TheCond != AsmCond::IfCond &&
2444      TheCondState.TheCond != AsmCond::ElseIfCond)
2445      Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
2446                          " an .elseif");
2447  TheCondState.TheCond = AsmCond::ElseIfCond;
2448
2449  bool LastIgnoreState = false;
2450  if (!TheCondStack.empty())
2451      LastIgnoreState = TheCondStack.back().Ignore;
2452  if (LastIgnoreState || TheCondState.CondMet) {
2453    TheCondState.Ignore = true;
2454    EatToEndOfStatement();
2455  }
2456  else {
2457    int64_t ExprValue;
2458    if (ParseAbsoluteExpression(ExprValue))
2459      return true;
2460
2461    if (getLexer().isNot(AsmToken::EndOfStatement))
2462      return TokError("unexpected token in '.elseif' directive");
2463
2464    Lex();
2465    TheCondState.CondMet = ExprValue;
2466    TheCondState.Ignore = !TheCondState.CondMet;
2467  }
2468
2469  return false;
2470}
2471
2472/// ParseDirectiveElse
2473/// ::= .else
2474bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
2475  if (getLexer().isNot(AsmToken::EndOfStatement))
2476    return TokError("unexpected token in '.else' directive");
2477
2478  Lex();
2479
2480  if (TheCondState.TheCond != AsmCond::IfCond &&
2481      TheCondState.TheCond != AsmCond::ElseIfCond)
2482      Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
2483                          ".elseif");
2484  TheCondState.TheCond = AsmCond::ElseCond;
2485  bool LastIgnoreState = false;
2486  if (!TheCondStack.empty())
2487    LastIgnoreState = TheCondStack.back().Ignore;
2488  if (LastIgnoreState || TheCondState.CondMet)
2489    TheCondState.Ignore = true;
2490  else
2491    TheCondState.Ignore = false;
2492
2493  return false;
2494}
2495
2496/// ParseDirectiveEndIf
2497/// ::= .endif
2498bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
2499  if (getLexer().isNot(AsmToken::EndOfStatement))
2500    return TokError("unexpected token in '.endif' directive");
2501
2502  Lex();
2503
2504  if ((TheCondState.TheCond == AsmCond::NoCond) ||
2505      TheCondStack.empty())
2506    Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
2507                        ".else");
2508  if (!TheCondStack.empty()) {
2509    TheCondState = TheCondStack.back();
2510    TheCondStack.pop_back();
2511  }
2512
2513  return false;
2514}
2515
2516/// ParseDirectiveFile
2517/// ::= .file [number] filename
2518/// ::= .file number directory filename
2519bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
2520  // FIXME: I'm not sure what this is.
2521  int64_t FileNumber = -1;
2522  SMLoc FileNumberLoc = getLexer().getLoc();
2523  if (getLexer().is(AsmToken::Integer)) {
2524    FileNumber = getTok().getIntVal();
2525    Lex();
2526
2527    if (FileNumber < 1)
2528      return TokError("file number less than one");
2529  }
2530
2531  if (getLexer().isNot(AsmToken::String))
2532    return TokError("unexpected token in '.file' directive");
2533
2534  // Usually the directory and filename together, otherwise just the directory.
2535  StringRef Path = getTok().getString();
2536  Path = Path.substr(1, Path.size()-2);
2537  Lex();
2538
2539  StringRef Directory;
2540  StringRef Filename;
2541  if (getLexer().is(AsmToken::String)) {
2542    if (FileNumber == -1)
2543      return TokError("explicit path specified, but no file number");
2544    Filename = getTok().getString();
2545    Filename = Filename.substr(1, Filename.size()-2);
2546    Directory = Path;
2547    Lex();
2548  } else {
2549    Filename = Path;
2550  }
2551
2552  if (getLexer().isNot(AsmToken::EndOfStatement))
2553    return TokError("unexpected token in '.file' directive");
2554
2555  if (FileNumber == -1)
2556    getStreamer().EmitFileDirective(Filename);
2557  else {
2558    if (getContext().getGenDwarfForAssembly() == true)
2559      Error(DirectiveLoc, "input can't have .file dwarf directives when -g is "
2560                        "used to generate dwarf debug info for assembly code");
2561
2562    if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename))
2563      Error(FileNumberLoc, "file number already allocated");
2564  }
2565
2566  return false;
2567}
2568
2569/// ParseDirectiveLine
2570/// ::= .line [number]
2571bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
2572  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2573    if (getLexer().isNot(AsmToken::Integer))
2574      return TokError("unexpected token in '.line' directive");
2575
2576    int64_t LineNumber = getTok().getIntVal();
2577    (void) LineNumber;
2578    Lex();
2579
2580    // FIXME: Do something with the .line.
2581  }
2582
2583  if (getLexer().isNot(AsmToken::EndOfStatement))
2584    return TokError("unexpected token in '.line' directive");
2585
2586  return false;
2587}
2588
2589
2590/// ParseDirectiveLoc
2591/// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
2592///                                [epilogue_begin] [is_stmt VALUE] [isa VALUE]
2593/// The first number is a file number, must have been previously assigned with
2594/// a .file directive, the second number is the line number and optionally the
2595/// third number is a column position (zero if not specified).  The remaining
2596/// optional items are .loc sub-directives.
2597bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
2598
2599  if (getLexer().isNot(AsmToken::Integer))
2600    return TokError("unexpected token in '.loc' directive");
2601  int64_t FileNumber = getTok().getIntVal();
2602  if (FileNumber < 1)
2603    return TokError("file number less than one in '.loc' directive");
2604  if (!getContext().isValidDwarfFileNumber(FileNumber))
2605    return TokError("unassigned file number in '.loc' directive");
2606  Lex();
2607
2608  int64_t LineNumber = 0;
2609  if (getLexer().is(AsmToken::Integer)) {
2610    LineNumber = getTok().getIntVal();
2611    if (LineNumber < 1)
2612      return TokError("line number less than one in '.loc' directive");
2613    Lex();
2614  }
2615
2616  int64_t ColumnPos = 0;
2617  if (getLexer().is(AsmToken::Integer)) {
2618    ColumnPos = getTok().getIntVal();
2619    if (ColumnPos < 0)
2620      return TokError("column position less than zero in '.loc' directive");
2621    Lex();
2622  }
2623
2624  unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
2625  unsigned Isa = 0;
2626  int64_t Discriminator = 0;
2627  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2628    for (;;) {
2629      if (getLexer().is(AsmToken::EndOfStatement))
2630        break;
2631
2632      StringRef Name;
2633      SMLoc Loc = getTok().getLoc();
2634      if (getParser().ParseIdentifier(Name))
2635        return TokError("unexpected token in '.loc' directive");
2636
2637      if (Name == "basic_block")
2638        Flags |= DWARF2_FLAG_BASIC_BLOCK;
2639      else if (Name == "prologue_end")
2640        Flags |= DWARF2_FLAG_PROLOGUE_END;
2641      else if (Name == "epilogue_begin")
2642        Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
2643      else if (Name == "is_stmt") {
2644        SMLoc Loc = getTok().getLoc();
2645        const MCExpr *Value;
2646        if (getParser().ParseExpression(Value))
2647          return true;
2648        // The expression must be the constant 0 or 1.
2649        if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
2650          int Value = MCE->getValue();
2651          if (Value == 0)
2652            Flags &= ~DWARF2_FLAG_IS_STMT;
2653          else if (Value == 1)
2654            Flags |= DWARF2_FLAG_IS_STMT;
2655          else
2656            return Error(Loc, "is_stmt value not 0 or 1");
2657        }
2658        else {
2659          return Error(Loc, "is_stmt value not the constant value of 0 or 1");
2660        }
2661      }
2662      else if (Name == "isa") {
2663        SMLoc Loc = getTok().getLoc();
2664        const MCExpr *Value;
2665        if (getParser().ParseExpression(Value))
2666          return true;
2667        // The expression must be a constant greater or equal to 0.
2668        if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
2669          int Value = MCE->getValue();
2670          if (Value < 0)
2671            return Error(Loc, "isa number less than zero");
2672          Isa = Value;
2673        }
2674        else {
2675          return Error(Loc, "isa number not a constant value");
2676        }
2677      }
2678      else if (Name == "discriminator") {
2679        if (getParser().ParseAbsoluteExpression(Discriminator))
2680          return true;
2681      }
2682      else {
2683        return Error(Loc, "unknown sub-directive in '.loc' directive");
2684      }
2685
2686      if (getLexer().is(AsmToken::EndOfStatement))
2687        break;
2688    }
2689  }
2690
2691  getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
2692                                      Isa, Discriminator, StringRef());
2693
2694  return false;
2695}
2696
2697/// ParseDirectiveStabs
2698/// ::= .stabs string, number, number, number
2699bool GenericAsmParser::ParseDirectiveStabs(StringRef Directive,
2700                                           SMLoc DirectiveLoc) {
2701  return TokError("unsupported directive '" + Directive + "'");
2702}
2703
2704/// ParseDirectiveCFISections
2705/// ::= .cfi_sections section [, section]
2706bool GenericAsmParser::ParseDirectiveCFISections(StringRef,
2707                                                 SMLoc DirectiveLoc) {
2708  StringRef Name;
2709  bool EH = false;
2710  bool Debug = false;
2711
2712  if (getParser().ParseIdentifier(Name))
2713    return TokError("Expected an identifier");
2714
2715  if (Name == ".eh_frame")
2716    EH = true;
2717  else if (Name == ".debug_frame")
2718    Debug = true;
2719
2720  if (getLexer().is(AsmToken::Comma)) {
2721    Lex();
2722
2723    if (getParser().ParseIdentifier(Name))
2724      return TokError("Expected an identifier");
2725
2726    if (Name == ".eh_frame")
2727      EH = true;
2728    else if (Name == ".debug_frame")
2729      Debug = true;
2730  }
2731
2732  getStreamer().EmitCFISections(EH, Debug);
2733
2734  return false;
2735}
2736
2737/// ParseDirectiveCFIStartProc
2738/// ::= .cfi_startproc
2739bool GenericAsmParser::ParseDirectiveCFIStartProc(StringRef,
2740                                                  SMLoc DirectiveLoc) {
2741  getStreamer().EmitCFIStartProc();
2742  return false;
2743}
2744
2745/// ParseDirectiveCFIEndProc
2746/// ::= .cfi_endproc
2747bool GenericAsmParser::ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc) {
2748  getStreamer().EmitCFIEndProc();
2749  return false;
2750}
2751
2752/// ParseRegisterOrRegisterNumber - parse register name or number.
2753bool GenericAsmParser::ParseRegisterOrRegisterNumber(int64_t &Register,
2754                                                     SMLoc DirectiveLoc) {
2755  unsigned RegNo;
2756
2757  if (getLexer().isNot(AsmToken::Integer)) {
2758    if (getParser().getTargetParser().ParseRegister(RegNo, DirectiveLoc,
2759      DirectiveLoc))
2760      return true;
2761    Register = getContext().getRegisterInfo().getDwarfRegNum(RegNo, true);
2762  } else
2763    return getParser().ParseAbsoluteExpression(Register);
2764
2765  return false;
2766}
2767
2768/// ParseDirectiveCFIDefCfa
2769/// ::= .cfi_def_cfa register,  offset
2770bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef,
2771                                               SMLoc DirectiveLoc) {
2772  int64_t Register = 0;
2773  if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
2774    return true;
2775
2776  if (getLexer().isNot(AsmToken::Comma))
2777    return TokError("unexpected token in directive");
2778  Lex();
2779
2780  int64_t Offset = 0;
2781  if (getParser().ParseAbsoluteExpression(Offset))
2782    return true;
2783
2784  getStreamer().EmitCFIDefCfa(Register, Offset);
2785  return false;
2786}
2787
2788/// ParseDirectiveCFIDefCfaOffset
2789/// ::= .cfi_def_cfa_offset offset
2790bool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef,
2791                                                     SMLoc DirectiveLoc) {
2792  int64_t Offset = 0;
2793  if (getParser().ParseAbsoluteExpression(Offset))
2794    return true;
2795
2796  getStreamer().EmitCFIDefCfaOffset(Offset);
2797  return false;
2798}
2799
2800/// ParseDirectiveCFIAdjustCfaOffset
2801/// ::= .cfi_adjust_cfa_offset adjustment
2802bool GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset(StringRef,
2803                                                        SMLoc DirectiveLoc) {
2804  int64_t Adjustment = 0;
2805  if (getParser().ParseAbsoluteExpression(Adjustment))
2806    return true;
2807
2808  getStreamer().EmitCFIAdjustCfaOffset(Adjustment);
2809  return false;
2810}
2811
2812/// ParseDirectiveCFIDefCfaRegister
2813/// ::= .cfi_def_cfa_register register
2814bool GenericAsmParser::ParseDirectiveCFIDefCfaRegister(StringRef,
2815                                                       SMLoc DirectiveLoc) {
2816  int64_t Register = 0;
2817  if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
2818    return true;
2819
2820  getStreamer().EmitCFIDefCfaRegister(Register);
2821  return false;
2822}
2823
2824/// ParseDirectiveCFIOffset
2825/// ::= .cfi_offset register, offset
2826bool GenericAsmParser::ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc) {
2827  int64_t Register = 0;
2828  int64_t Offset = 0;
2829
2830  if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
2831    return true;
2832
2833  if (getLexer().isNot(AsmToken::Comma))
2834    return TokError("unexpected token in directive");
2835  Lex();
2836
2837  if (getParser().ParseAbsoluteExpression(Offset))
2838    return true;
2839
2840  getStreamer().EmitCFIOffset(Register, Offset);
2841  return false;
2842}
2843
2844/// ParseDirectiveCFIRelOffset
2845/// ::= .cfi_rel_offset register, offset
2846bool GenericAsmParser::ParseDirectiveCFIRelOffset(StringRef,
2847                                                  SMLoc DirectiveLoc) {
2848  int64_t Register = 0;
2849
2850  if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
2851    return true;
2852
2853  if (getLexer().isNot(AsmToken::Comma))
2854    return TokError("unexpected token in directive");
2855  Lex();
2856
2857  int64_t Offset = 0;
2858  if (getParser().ParseAbsoluteExpression(Offset))
2859    return true;
2860
2861  getStreamer().EmitCFIRelOffset(Register, Offset);
2862  return false;
2863}
2864
2865static bool isValidEncoding(int64_t Encoding) {
2866  if (Encoding & ~0xff)
2867    return false;
2868
2869  if (Encoding == dwarf::DW_EH_PE_omit)
2870    return true;
2871
2872  const unsigned Format = Encoding & 0xf;
2873  if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
2874      Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
2875      Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
2876      Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
2877    return false;
2878
2879  const unsigned Application = Encoding & 0x70;
2880  if (Application != dwarf::DW_EH_PE_absptr &&
2881      Application != dwarf::DW_EH_PE_pcrel)
2882    return false;
2883
2884  return true;
2885}
2886
2887/// ParseDirectiveCFIPersonalityOrLsda
2888/// ::= .cfi_personality encoding, [symbol_name]
2889/// ::= .cfi_lsda encoding, [symbol_name]
2890bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal,
2891                                                    SMLoc DirectiveLoc) {
2892  int64_t Encoding = 0;
2893  if (getParser().ParseAbsoluteExpression(Encoding))
2894    return true;
2895  if (Encoding == dwarf::DW_EH_PE_omit)
2896    return false;
2897
2898  if (!isValidEncoding(Encoding))
2899    return TokError("unsupported encoding.");
2900
2901  if (getLexer().isNot(AsmToken::Comma))
2902    return TokError("unexpected token in directive");
2903  Lex();
2904
2905  StringRef Name;
2906  if (getParser().ParseIdentifier(Name))
2907    return TokError("expected identifier in directive");
2908
2909  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2910
2911  if (IDVal == ".cfi_personality")
2912    getStreamer().EmitCFIPersonality(Sym, Encoding);
2913  else {
2914    assert(IDVal == ".cfi_lsda");
2915    getStreamer().EmitCFILsda(Sym, Encoding);
2916  }
2917  return false;
2918}
2919
2920/// ParseDirectiveCFIRememberState
2921/// ::= .cfi_remember_state
2922bool GenericAsmParser::ParseDirectiveCFIRememberState(StringRef IDVal,
2923                                                      SMLoc DirectiveLoc) {
2924  getStreamer().EmitCFIRememberState();
2925  return false;
2926}
2927
2928/// ParseDirectiveCFIRestoreState
2929/// ::= .cfi_remember_state
2930bool GenericAsmParser::ParseDirectiveCFIRestoreState(StringRef IDVal,
2931                                                     SMLoc DirectiveLoc) {
2932  getStreamer().EmitCFIRestoreState();
2933  return false;
2934}
2935
2936/// ParseDirectiveCFISameValue
2937/// ::= .cfi_same_value register
2938bool GenericAsmParser::ParseDirectiveCFISameValue(StringRef IDVal,
2939                                                  SMLoc DirectiveLoc) {
2940  int64_t Register = 0;
2941
2942  if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
2943    return true;
2944
2945  getStreamer().EmitCFISameValue(Register);
2946
2947  return false;
2948}
2949
2950/// ParseDirectiveCFIRestore
2951/// ::= .cfi_restore register
2952bool GenericAsmParser::ParseDirectiveCFIRestore(StringRef IDVal,
2953						SMLoc DirectiveLoc) {
2954  int64_t Register = 0;
2955  if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
2956    return true;
2957
2958  getStreamer().EmitCFIRestore(Register);
2959
2960  return false;
2961}
2962
2963/// ParseDirectiveCFIEscape
2964/// ::= .cfi_escape expression[,...]
2965bool GenericAsmParser::ParseDirectiveCFIEscape(StringRef IDVal,
2966					       SMLoc DirectiveLoc) {
2967  std::string Values;
2968  int64_t CurrValue;
2969  if (getParser().ParseAbsoluteExpression(CurrValue))
2970    return true;
2971
2972  Values.push_back((uint8_t)CurrValue);
2973
2974  while (getLexer().is(AsmToken::Comma)) {
2975    Lex();
2976
2977    if (getParser().ParseAbsoluteExpression(CurrValue))
2978      return true;
2979
2980    Values.push_back((uint8_t)CurrValue);
2981  }
2982
2983  getStreamer().EmitCFIEscape(Values);
2984  return false;
2985}
2986
2987/// ParseDirectiveCFISignalFrame
2988/// ::= .cfi_signal_frame
2989bool GenericAsmParser::ParseDirectiveCFISignalFrame(StringRef Directive,
2990                                                    SMLoc DirectiveLoc) {
2991  if (getLexer().isNot(AsmToken::EndOfStatement))
2992    return Error(getLexer().getLoc(),
2993                 "unexpected token in '" + Directive + "' directive");
2994
2995  getStreamer().EmitCFISignalFrame();
2996
2997  return false;
2998}
2999
3000/// ParseDirectiveMacrosOnOff
3001/// ::= .macros_on
3002/// ::= .macros_off
3003bool GenericAsmParser::ParseDirectiveMacrosOnOff(StringRef Directive,
3004                                                 SMLoc DirectiveLoc) {
3005  if (getLexer().isNot(AsmToken::EndOfStatement))
3006    return Error(getLexer().getLoc(),
3007                 "unexpected token in '" + Directive + "' directive");
3008
3009  getParser().MacrosEnabled = Directive == ".macros_on";
3010
3011  return false;
3012}
3013
3014/// ParseDirectiveMacro
3015/// ::= .macro name [parameters]
3016bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive,
3017                                           SMLoc DirectiveLoc) {
3018  StringRef Name;
3019  if (getParser().ParseIdentifier(Name))
3020    return TokError("expected identifier in directive");
3021
3022  std::vector<StringRef> Parameters;
3023  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3024    for(;;) {
3025      StringRef Parameter;
3026      if (getParser().ParseIdentifier(Parameter))
3027        return TokError("expected identifier in directive");
3028      Parameters.push_back(Parameter);
3029
3030      if (getLexer().isNot(AsmToken::Comma))
3031        break;
3032      Lex();
3033    }
3034  }
3035
3036  if (getLexer().isNot(AsmToken::EndOfStatement))
3037    return TokError("unexpected token in '.macro' directive");
3038
3039  // Eat the end of statement.
3040  Lex();
3041
3042  AsmToken EndToken, StartToken = getTok();
3043
3044  // Lex the macro definition.
3045  for (;;) {
3046    // Check whether we have reached the end of the file.
3047    if (getLexer().is(AsmToken::Eof))
3048      return Error(DirectiveLoc, "no matching '.endmacro' in definition");
3049
3050    // Otherwise, check whether we have reach the .endmacro.
3051    if (getLexer().is(AsmToken::Identifier) &&
3052        (getTok().getIdentifier() == ".endm" ||
3053         getTok().getIdentifier() == ".endmacro")) {
3054      EndToken = getTok();
3055      Lex();
3056      if (getLexer().isNot(AsmToken::EndOfStatement))
3057        return TokError("unexpected token in '" + EndToken.getIdentifier() +
3058                        "' directive");
3059      break;
3060    }
3061
3062    // Otherwise, scan til the end of the statement.
3063    getParser().EatToEndOfStatement();
3064  }
3065
3066  if (getParser().MacroMap.lookup(Name)) {
3067    return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
3068  }
3069
3070  const char *BodyStart = StartToken.getLoc().getPointer();
3071  const char *BodyEnd = EndToken.getLoc().getPointer();
3072  StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
3073  getParser().MacroMap[Name] = new Macro(Name, Body, Parameters);
3074  return false;
3075}
3076
3077/// ParseDirectiveEndMacro
3078/// ::= .endm
3079/// ::= .endmacro
3080bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive,
3081                                           SMLoc DirectiveLoc) {
3082  if (getLexer().isNot(AsmToken::EndOfStatement))
3083    return TokError("unexpected token in '" + Directive + "' directive");
3084
3085  // If we are inside a macro instantiation, terminate the current
3086  // instantiation.
3087  if (!getParser().ActiveMacros.empty()) {
3088    getParser().HandleMacroExit();
3089    return false;
3090  }
3091
3092  // Otherwise, this .endmacro is a stray entry in the file; well formed
3093  // .endmacro directives are handled during the macro definition parsing.
3094  return TokError("unexpected '" + Directive + "' in file, "
3095                  "no current macro definition");
3096}
3097
3098/// ParseDirectivePurgeMacro
3099/// ::= .purgem
3100bool GenericAsmParser::ParseDirectivePurgeMacro(StringRef Directive,
3101                                                SMLoc DirectiveLoc) {
3102  StringRef Name;
3103  if (getParser().ParseIdentifier(Name))
3104    return TokError("expected identifier in '.purgem' directive");
3105
3106  if (getLexer().isNot(AsmToken::EndOfStatement))
3107    return TokError("unexpected token in '.purgem' directive");
3108
3109  StringMap<Macro*>::iterator I = getParser().MacroMap.find(Name);
3110  if (I == getParser().MacroMap.end())
3111    return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
3112
3113  // Undefine the macro.
3114  delete I->getValue();
3115  getParser().MacroMap.erase(I);
3116  return false;
3117}
3118
3119bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) {
3120  getParser().CheckForValidSection();
3121
3122  const MCExpr *Value;
3123
3124  if (getParser().ParseExpression(Value))
3125    return true;
3126
3127  if (getLexer().isNot(AsmToken::EndOfStatement))
3128    return TokError("unexpected token in directive");
3129
3130  if (DirName[1] == 's')
3131    getStreamer().EmitSLEB128Value(Value);
3132  else
3133    getStreamer().EmitULEB128Value(Value);
3134
3135  return false;
3136}
3137
3138bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) {
3139  const MCExpr *Value;
3140
3141  if (ParseExpression(Value))
3142    return true;
3143
3144  int64_t Count;
3145  if (!Value->EvaluateAsAbsolute(Count))
3146    return TokError("Cannot evaluate value");
3147
3148  if (Count < 0)
3149    return TokError("Count is negative");
3150
3151  AsmToken EndToken, StartToken = getTok();
3152  unsigned Nest = 1;
3153
3154  // Lex the macro definition.
3155  for (;;) {
3156    // Check whether we have reached the end of the file.
3157    if (getLexer().is(AsmToken::Eof))
3158      return Error(DirectiveLoc, "no matching '.endr' in definition");
3159
3160    // Chcek if we have a nested .rept.
3161    if (getLexer().is(AsmToken::Identifier) &&
3162        (getTok().getIdentifier() == ".rept")) {
3163      Nest++;
3164      EatToEndOfStatement();
3165      continue;
3166    }
3167
3168    // Otherwise, check whether we have reach the .endr.
3169    if (getLexer().is(AsmToken::Identifier) &&
3170        (getTok().getIdentifier() == ".endr")) {
3171      Nest--;
3172      if (Nest == 0) {
3173        EndToken = getTok();
3174        Lex();
3175        if (getLexer().isNot(AsmToken::EndOfStatement))
3176          return TokError("unexpected token in '.endr' directive");
3177        break;
3178      }
3179    }
3180
3181    // Otherwise, scan til the end of the statement.
3182    EatToEndOfStatement();
3183  }
3184
3185  const char *BodyStart = StartToken.getLoc().getPointer();
3186  const char *BodyEnd = EndToken.getLoc().getPointer();
3187  StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
3188
3189  SmallString<256> Buf;
3190  raw_svector_ostream OS(Buf);
3191  for (int i = 0; i < Count; i++)
3192    OS << Body;
3193  OS << ".endr\n";
3194
3195  MemoryBuffer *Instantiation =
3196    MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
3197
3198  CurBuffer = SrcMgr.AddNewSourceBuffer(Instantiation, SMLoc());
3199  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
3200
3201  ActiveRept.push_back(getTok().getLoc());
3202
3203  return false;
3204}
3205
3206bool AsmParser::ParseDirectiveEndRept(SMLoc DirectiveLoc) {
3207  if (ActiveRept.empty())
3208    return TokError("unexpected '.endr' directive, no current .rept");
3209
3210  // The only .repl that should get here are the ones created by
3211  // ParseDirectiveRept.
3212  assert(getLexer().is(AsmToken::EndOfStatement));
3213
3214  JumpToLoc(ActiveRept.back());
3215  ActiveRept.pop_back();
3216  return false;
3217}
3218
3219/// \brief Create an MCAsmParser instance.
3220MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM,
3221                                     MCContext &C, MCStreamer &Out,
3222                                     const MCAsmInfo &MAI) {
3223  return new AsmParser(SM, C, Out, MAI);
3224}
3225