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