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