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