1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This class implements the parser for assembly files.
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/APFloat.h"
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/SmallString.h"
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/StringMap.h"
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/StringSwitch.h"
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/Twine.h"
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCAsmInfo.h"
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCContext.h"
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCDwarf.h"
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCExpr.h"
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCParser/AsmCond.h"
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCParser/AsmLexer.h"
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCParser/MCAsmParser.h"
26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCRegisterInfo.h"
28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCSectionMachO.h"
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCStreamer.h"
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCSymbol.h"
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCTargetAsmParser.h"
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/CommandLine.h"
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/MathExtras.h"
34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/MemoryBuffer.h"
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/SourceMgr.h"
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h"
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <cctype>
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <vector>
39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm;
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<bool>
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanFatalAssemblerWarnings("fatal-assembler-warnings",
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       cl::desc("Consider warnings as error"));
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace {
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// \brief Helper class for tracking macro definitions.
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct Macro {
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringRef Name;
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringRef Body;
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::vector<StringRef> Parameters;
52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Macro(StringRef N, StringRef B, const std::vector<StringRef> &P) :
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Name(N), Body(B), Parameters(P) {}
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// \brief Helper class for storing information about an active macro
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// instantiation.
60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct MacroInstantiation {
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// The macro being instantiated.
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const Macro *TheMacro;
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// The macro instantiation with substitutions.
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MemoryBuffer *Instantiation;
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// The location of the instantiation.
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc InstantiationLoc;
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// The location where parsing should resume upon instantiation completion.
71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc ExitLoc;
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL,
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     MemoryBuffer *I);
76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// \brief The concrete assembly parser instance.
79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass AsmParser : public MCAsmParser {
80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  friend class GenericAsmParser;
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  AsmParser(const AsmParser &);   // DO NOT IMPLEMENT
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void operator=(const AsmParser &);  // DO NOT IMPLEMENT
84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate:
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  AsmLexer Lexer;
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MCContext &Ctx;
87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MCStreamer &Out;
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCAsmInfo &MAI;
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SourceMgr &SrcMgr;
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SourceMgr::DiagHandlerTy SavedDiagHandler;
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void *SavedDiagContext;
92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MCAsmParserExtension *GenericParser;
93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MCAsmParserExtension *PlatformParser;
94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// This is the current buffer index we're lexing from as managed by the
96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// SourceMgr object.
97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int CurBuffer;
98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  AsmCond TheCondState;
100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  std::vector<AsmCond> TheCondStack;
101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// DirectiveMap - This is a table handlers for directives.  Each handler is
103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// invoked after the directive identifier is read and is responsible for
104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// parsing and validating the rest of the directive.  The handler is passed
105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// in the directive name and the location of the directive keyword.
106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringMap<std::pair<MCAsmParserExtension*, DirectiveHandler> > DirectiveMap;
107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// MacroMap - Map of currently defined macros.
109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringMap<Macro*> MacroMap;
110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// ActiveMacros - Stack of active macro instantiations.
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  std::vector<MacroInstantiation*> ActiveMacros;
113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// Boolean tracking whether macro substitution is enabled.
115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned MacrosEnabled : 1;
116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// Flag tracking whether any errors have been encountered.
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned HadError : 1;
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// The values from the last parsed cpp hash file line comment if any.
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StringRef CppHashFilename;
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t CppHashLineNumber;
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SMLoc CppHashLoc;
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            const MCAsmInfo &MAI);
128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ~AsmParser();
129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false);
131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void AddDirectiveHandler(MCAsmParserExtension *Object,
133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                           StringRef Directive,
134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                           DirectiveHandler Handler) {
135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    DirectiveMap[Directive] = std::make_pair(Object, Handler);
136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// @name MCAsmParser Interface
140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// {
141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual SourceMgr &getSourceManager() { return SrcMgr; }
143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual MCAsmLexer &getLexer() { return Lexer; }
144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual MCContext &getContext() { return Ctx; }
145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual MCStreamer &getStreamer() { return Out; }
146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  virtual bool Warning(SMLoc L, const Twine &Msg);
148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual bool Error(SMLoc L, const Twine &Msg);
149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const AsmToken &Lex();
151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseExpression(const MCExpr *&Res);
153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc);
154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual bool ParseAbsoluteExpression(int64_t &Res);
156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// }
158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate:
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void CheckForValidSection();
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseStatement();
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void EatToEndOfLine();
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseCppHashLineFilenameComment(const SMLoc &L);
165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M);
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool expandMacro(SmallString<256> &Buf, StringRef Body,
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   const std::vector<StringRef> &Parameters,
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   const std::vector<std::vector<AsmToken> > &A,
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   const SMLoc &L);
171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void HandleMacroExit();
172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void PrintMacroInstantiations();
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void PrintMessage(SMLoc Loc, const Twine &Msg, const char *Type,
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                    bool ShowLine = true) const {
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SrcMgr.PrintMessage(Loc, Msg, Type, ShowLine);
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static void DiagHandler(const SMDiagnostic &Diag, void *Context);
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// EnterIncludeFile - Enter the specified file. This returns true on failure.
181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool EnterIncludeFile(const std::string &Filename);
182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// \brief Reset the current lexer position to that given by \arg Loc. The
184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// current token is not set; clients should ensure Lex() is called
185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// subsequently.
186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void JumpToLoc(SMLoc Loc);
187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void EatToEndOfStatement();
189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// \brief Parse up to the end of statement and a return the contents from the
191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// current token until the end of the statement; the current token on exit
192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// will be either the EndOfStatement or EOF.
193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringRef ParseStringToEndOfStatement();
194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseAssignment(StringRef Name, bool allow_redef);
196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// and set \arg Res to the identifier contents.
204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseIdentifier(StringRef &Res);
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Directive Parsing.
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // ".ascii", ".asciiz", ".string"
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveRealValue(const fltSemantics &); // ".single", ...
212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveFill(); // ".fill"
213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveSpace(); // ".space"
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveZero(); // ".zero"
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveSet(StringRef IDVal, bool allow_redef); // ".set", ".equ", ".equiv"
216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveOrg(); // ".org"
217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // ".align{,32}", ".p2align{,w,l}"
218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// accepts a single symbol (which should be a label or an external).
222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr);
223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveAbort(); // ".abort"
227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveInclude(); // ".include"
228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if"
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ".ifdef" or ".ifndef", depending on expect_defined
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else"
234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// ParseEscapedString - Parse the current token as a string which may include
237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// escaped characters and return the string contents.
238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseEscapedString(std::string &Data);
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCExpr *ApplyModifierToExpr(const MCExpr *E,
24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                    MCSymbolRefExpr::VariantKind Variant);
242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// \brief Generic implementations of directive handling, etc. which is shared
245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// (or the default, at least) for all assembler parser.
246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass GenericAsmParser : public MCAsmParserExtension {
247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  template<bool (GenericAsmParser::*Handler)(StringRef, SMLoc)>
248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void AddDirectiveHandler(StringRef Directive) {
249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    getParser().AddDirectiveHandler(this, Directive,
250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                    HandleDirective<GenericAsmParser, Handler>);
251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  GenericAsmParser() {}
254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  AsmParser &getParser() {
256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return (AsmParser&) this->MCAsmParserExtension::getParser();
257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual void Initialize(MCAsmParser &Parser) {
260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Call the base implementation.
261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    this->MCAsmParserExtension::Initialize(Parser);
262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Debugging directives.
264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveFile>(".file");
265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLine>(".line");
266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLoc>(".loc");
26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveStabs>(".stabs");
26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // CFI directives.
27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFISections>(
27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                               ".cfi_sections");
27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIStartProc>(
27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                              ".cfi_startproc");
27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIEndProc>(
27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                                ".cfi_endproc");
27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfa>(
27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                         ".cfi_def_cfa");
27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset>(
27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                         ".cfi_def_cfa_offset");
28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset>(
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                      ".cfi_adjust_cfa_offset");
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister>(
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                       ".cfi_def_cfa_register");
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIOffset>(
28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                                 ".cfi_offset");
28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIRelOffset>(
28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                             ".cfi_rel_offset");
28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<
28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman     &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_personality");
29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<
29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_lsda");
29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<
29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      &GenericAsmParser::ParseDirectiveCFIRememberState>(".cfi_remember_state");
29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<
29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      &GenericAsmParser::ParseDirectiveCFIRestoreState>(".cfi_restore_state");
29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<
29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      &GenericAsmParser::ParseDirectiveCFISameValue>(".cfi_same_value");
298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Macro directives.
300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      ".macros_on");
302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      ".macros_off");
304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacro>(".macro");
305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endm");
306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endmacro");
30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".sleb128");
30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".uleb128");
310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc);
315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc);
316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc);
31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc);
31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFISections(StringRef, SMLoc DirectiveLoc);
31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc);
32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc);
32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFIDefCfa(StringRef, SMLoc DirectiveLoc);
32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFIDefCfaOffset(StringRef, SMLoc DirectiveLoc);
32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFIAdjustCfaOffset(StringRef, SMLoc DirectiveLoc);
32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc);
32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc);
32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFIRelOffset(StringRef, SMLoc DirectiveLoc);
32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFIPersonalityOrLsda(StringRef, SMLoc DirectiveLoc);
32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFIRememberState(StringRef, SMLoc DirectiveLoc);
32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFIRestoreState(StringRef, SMLoc DirectiveLoc);
33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveCFISameValue(StringRef, SMLoc DirectiveLoc);
331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc);
333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ParseDirectiveEndMacro(StringRef, SMLoc DirectiveLoc);
33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ParseDirectiveLEB128(StringRef, SMLoc);
337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace llvm {
342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanextern MCAsmParserExtension *createDarwinAsmParser();
344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanextern MCAsmParserExtension *createELFAsmParser();
34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanextern MCAsmParserExtension *createCOFFAsmParser();
346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanenum { DEFAULT_ADDRSPACE = 0 };
350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanAsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                     MCStreamer &_Out, const MCAsmInfo &_MAI)
35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    GenericParser(new GenericAsmParser), PlatformParser(0),
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0) {
35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Save the old handler.
35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SavedDiagHandler = SrcMgr.getDiagHandler();
35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SavedDiagContext = SrcMgr.getDiagContext();
35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Set our own handler which calls the saved handler.
36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SrcMgr.setDiagHandler(DiagHandler, this);
361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Initialize the generic parser.
364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  GenericParser->Initialize(*this);
365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Initialize the platform / file format parser.
367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //
368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // FIXME: This is a hack, we need to (majorly) cleanup how these objects are
369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // created.
37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (_MAI.hasMicrosoftFastStdCallMangling()) {
37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PlatformParser = createCOFFAsmParser();
37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PlatformParser->Initialize(*this);
37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else if (_MAI.hasSubsectionsViaSymbols()) {
374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    PlatformParser = createDarwinAsmParser();
375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    PlatformParser->Initialize(*this);
376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else {
377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    PlatformParser = createELFAsmParser();
378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    PlatformParser->Initialize(*this);
379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanAsmParser::~AsmParser() {
383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  assert(ActiveMacros.empty() && "Unexpected active macro instantiation!");
384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Destroy any macros.
386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (StringMap<Macro*>::iterator it = MacroMap.begin(),
387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman         ie = MacroMap.end(); it != ie; ++it)
388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    delete it->getValue();
389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  delete PlatformParser;
391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  delete GenericParser;
392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid AsmParser::PrintMacroInstantiations() {
395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Print the active macro instantiation stack.
396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (std::vector<MacroInstantiation*>::const_reverse_iterator
397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman         it = ActiveMacros.rbegin(), ie = ActiveMacros.rend(); it != ie; ++it)
398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    PrintMessage((*it)->InstantiationLoc, "while in macro instantiation",
399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                 "note");
400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool AsmParser::Warning(SMLoc L, const Twine &Msg) {
40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (FatalAssemblerWarnings)
40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Error(L, Msg);
40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PrintMessage(L, Msg, "warning");
406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  PrintMacroInstantiations();
40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::Error(SMLoc L, const Twine &Msg) {
41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  HadError = true;
41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PrintMessage(L, Msg, "error");
413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  PrintMacroInstantiations();
414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return true;
415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::EnterIncludeFile(const std::string &Filename) {
41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::string IncludedFile;
41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (NewBuf == -1)
421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  CurBuffer = NewBuf;
42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid AsmParser::JumpToLoc(SMLoc Loc) {
431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), Loc.getPointer());
433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanconst AsmToken &AsmParser::Lex() {
436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const AsmToken *tok = &Lexer.Lex();
43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (tok->is(AsmToken::Eof)) {
439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // If this is the end of an included file, pop the parent file off the
440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // include stack.
441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParentIncludeLoc != SMLoc()) {
443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      JumpToLoc(ParentIncludeLoc);
444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      tok = &Lexer.Lex();
445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (tok->is(AsmToken::Error))
449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Error(Lexer.getErrLoc(), Lexer.getErr());
45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return *tok;
452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Create the initial section, if requested.
456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!NoInitialTextSection)
45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Out.InitSections();
458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Prime the lexer.
460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  HadError = false;
463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  AsmCond StartingCondState = TheCondState;
464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // While we have input, parse each statement.
466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  while (Lexer.isNot(AsmToken::Eof)) {
467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (!ParseStatement()) continue;
46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // We had an error, validate that one was emitted and recover by skipping to
47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // the next line.
47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(HadError && "Parse statement returned an error, but none emitted!");
472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EatToEndOfStatement();
473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (TheCondState.TheCond != StartingCondState.TheCond ||
476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      TheCondState.Ignore != StartingCondState.Ignore)
477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unmatched .ifs or .elses");
478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Check to see there are no empty DwarfFile slots.
480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const std::vector<MCDwarfFile *> &MCDwarfFiles =
481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    getContext().getMCDwarfFiles();
482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!MCDwarfFiles[i])
484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      TokError("unassigned file number: " + Twine(i) + " for .file directives");
48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Check to see that all assembler local symbols were actually defined.
48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Targets that don't do subsections via symbols may not want this, though,
48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // so conservatively exclude them. Only do this if we're finalizing, though,
49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // as otherwise we won't necessarilly have seen everything yet.
49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) {
49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCContext::SymbolTable &Symbols = getContext().getSymbols();
49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (MCContext::SymbolTable::const_iterator i = Symbols.begin(),
49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         e = Symbols.end();
49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         i != e; ++i) {
49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCSymbol *Sym = i->getValue();
49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Variable symbols may not be marked as defined, so check those
49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // explicitly. If we know it's a variable, we have a definition for
49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // the purposes of this check.
50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // FIXME: We would really like to refer back to where the symbol was
50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // first referenced for a source location. We need to add something
50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // to track that. Currently, we just point to the end of the file.
50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        PrintMessage(getLexer().getLoc(), "assembler local symbol '" +
50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     Sym->getName() + "' not defined", "error", false);
506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Finalize the output stream if there are no errors and if the client wants
511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // us to.
51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!HadError && !NoFinalize)
513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Out.Finish();
514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return HadError;
516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid AsmParser::CheckForValidSection() {
51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!getStreamer().getCurrentSection()) {
52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    TokError("expected section directive before assembly directive");
52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Out.SwitchSection(Ctx.getMachOSection(
52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        "__TEXT", "__text",
52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        0, SectionKind::getText()));
52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid AsmParser::EatToEndOfStatement() {
530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  while (Lexer.isNot(AsmToken::EndOfStatement) &&
531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman         Lexer.isNot(AsmToken::Eof))
532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Eat EOL.
535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Lexer.is(AsmToken::EndOfStatement))
536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanStringRef AsmParser::ParseStringToEndOfStatement() {
540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const char *Start = getTok().getLoc().getPointer();
541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  while (Lexer.isNot(AsmToken::EndOfStatement) &&
543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman         Lexer.isNot(AsmToken::Eof))
544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const char *End = getTok().getLoc().getPointer();
547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return StringRef(Start, End - Start);
548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseParenExpr - Parse a paren expression and return it.
551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// NOTE: This assumes the leading '(' has already been consumed.
552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// parenexpr ::= expr)
554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseExpression(Res)) return true;
557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Lexer.isNot(AsmToken::RParen))
558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("expected ')' in parentheses expression");
559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  EndLoc = Lexer.getLoc();
560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseBracketExpr - Parse a bracket expression and return it.
56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// NOTE: This assumes the leading '[' has already been consumed.
56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// bracketexpr ::= expr]
56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ParseExpression(Res)) return true;
57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Lexer.isNot(AsmToken::RBrac))
57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("expected ']' in brackets expression");
57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  EndLoc = Lexer.getLoc();
57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Lex();
57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParsePrimaryExpr - Parse a primary expression and return it.
579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  primaryexpr ::= (parenexpr
580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  primaryexpr ::= symbol
581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  primaryexpr ::= number
582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  primaryexpr ::= '.'
583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  primaryexpr ::= ~,+,- primaryexpr
584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  switch (Lexer.getKind()) {
586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  default:
587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unknown token in expression");
58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If we have an error assume that we've already handled it.
58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::Error:
59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::Exclaim:
592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex(); // Eat the operator.
593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParsePrimaryExpr(Res, EndLoc))
594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Res = MCUnaryExpr::CreateLNot(Res, getContext());
596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::Dollar:
598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::String:
599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::Identifier: {
60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    EndLoc = Lexer.getLoc();
60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    StringRef Identifier;
60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (ParseIdentifier(Identifier))
60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // This is a symbol reference.
60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::pair<StringRef, StringRef> Split = Identifier.split('@');
608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MCSymbol *Sym = getContext().GetOrCreateSymbol(Split.first);
609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Lookup the symbol variant if used.
611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Split.first.size() != Identifier.size()) {
613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Variant == MCSymbolRefExpr::VK_Invalid) {
61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Variant = MCSymbolRefExpr::VK_None;
61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return TokError("invalid variant '" + Split.second + "'");
61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // If this is an absolute variable reference, substitute it now to preserve
621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // semantics in the face of reassignment.
622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) {
623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Variant)
62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return Error(EndLoc, "unexpected modifier on variable reference");
625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Res = Sym->getVariableValue();
627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return false;
628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Otherwise create a symbol ref.
631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::Integer: {
635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SMLoc Loc = getTok().getLoc();
636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    int64_t IntVal = getTok().getIntVal();
637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Res = MCConstantExpr::Create(IntVal, getContext());
638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EndLoc = Lexer.getLoc();
639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex(); // Eat token.
640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Look for 'b' or 'f' following an Integer as a directional label
641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Lexer.getKind() == AsmToken::Identifier) {
642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      StringRef IDVal = getTok().getString();
643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (IDVal == "f" || IDVal == "b"){
644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal,
645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                                      IDVal == "f" ? 1 : 0);
646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                      getContext());
648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if(IDVal == "b" && Sym->isUndefined())
649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          return Error(Loc, "invalid reference to undefined symbol");
650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        EndLoc = Lexer.getLoc();
651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Lex(); // Eat identifier.
652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::Real: {
65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    APFloat RealVal(APFloat::IEEEdouble, getTok().getString());
65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Res = MCConstantExpr::Create(IntVal, getContext());
66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lex(); // Eat token.
66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::Dot: {
664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // This is a '.' reference, which references the current PC.  Emit a
665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // temporary label to the streamer and refer to it.
666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MCSymbol *Sym = Ctx.CreateTempSymbol();
667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Out.EmitLabel(Sym);
668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EndLoc = Lexer.getLoc();
670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex(); // Eat identifier.
671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::LParen:
674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex(); // Eat the '('.
675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return ParseParenExpr(Res, EndLoc);
67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::LBrac:
67719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!PlatformParser->HasBracketExpressions())
67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TokError("brackets expression not supported on this target");
67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lex(); // Eat the '['.
68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return ParseBracketExpr(Res, EndLoc);
681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::Minus:
682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex(); // Eat the operator.
683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParsePrimaryExpr(Res, EndLoc))
684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Res = MCUnaryExpr::CreateMinus(Res, getContext());
686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::Plus:
688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex(); // Eat the operator.
689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParsePrimaryExpr(Res, EndLoc))
690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Res = MCUnaryExpr::CreatePlus(Res, getContext());
692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::Tilde:
694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex(); // Eat the operator.
695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParsePrimaryExpr(Res, EndLoc))
696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Res = MCUnaryExpr::CreateNot(Res, getContext());
698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseExpression(const MCExpr *&Res) {
703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc EndLoc;
704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return ParseExpression(Res, EndLoc);
705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst MCExpr *
70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanAsmParser::ApplyModifierToExpr(const MCExpr *E,
70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               MCSymbolRefExpr::VariantKind Variant) {
71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Recurse over the given expression, rebuilding it to apply the given variant
71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // if there is exactly one symbol.
71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (E->getKind()) {
71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Target:
71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Constant:
71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 0;
71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::SymbolRef: {
71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (SRE->getKind() != MCSymbolRefExpr::VK_None) {
72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      TokError("invalid variant on expression '" +
72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               getTok().getIdentifier() + "' (already modified)");
72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return E;
72419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
72519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
72619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
72819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
72919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Unary: {
73019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCExpr *Sub = ApplyModifierToExpr(UE->getSubExpr(), Variant);
73219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!Sub)
73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return 0;
73419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return MCUnaryExpr::Create(UE->getOpcode(), Sub, getContext());
73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
73719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Binary: {
73819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
73919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCExpr *LHS = ApplyModifierToExpr(BE->getLHS(), Variant);
74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCExpr *RHS = ApplyModifierToExpr(BE->getRHS(), Variant);
74119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
74219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!LHS && !RHS)
74319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return 0;
74419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
74519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!LHS) LHS = BE->getLHS();
74619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!RHS) RHS = BE->getRHS();
74719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
74819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
74919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
75019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
75119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
75219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(0 && "Invalid expression kind!");
75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return 0;
75419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
75519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseExpression - Parse an expression and return it.
75719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
75819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///  expr ::= expr &&,|| expr               -> lowest.
75919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///  expr ::= expr |,^,&,! expr
76019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///  expr ::= expr ==,!=,<>,<,<=,>,>= expr
76119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///  expr ::= expr <<,>> expr
76219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///  expr ::= expr +,- expr
76319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///  expr ::= expr *,/,% expr               -> highest.
764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  expr ::= primaryexpr
765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Parse the expression.
768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Res = 0;
769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
77219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // As a special case, we support 'a op b @ modifier' by rewriting the
77319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // expression to include the modifier. This is inefficient, but in general we
77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // expect users to use 'a@modifier op b'.
77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Lexer.getKind() == AsmToken::At) {
77619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lex();
77719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
77819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Lexer.isNot(AsmToken::Identifier))
77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TokError("unexpected symbol modifier following '@'");
78019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
78119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbolRefExpr::VariantKind Variant =
78219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier());
78319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Variant == MCSymbolRefExpr::VK_Invalid)
78419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TokError("invalid variant '" + getTok().getIdentifier() + "'");
78519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
78619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCExpr *ModifiedRes = ApplyModifierToExpr(Res, Variant);
78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!ModifiedRes) {
78819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TokError("invalid modifier '" + getTok().getIdentifier() +
78919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      "' (no symbols present)");
79019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
79119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
79219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
79319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Res = ModifiedRes;
79419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lex();
79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Try to constant fold it up front, if possible.
798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t Value;
799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Res->EvaluateAsAbsolute(Value))
800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Res = MCConstantExpr::Create(Value, getContext());
801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Res = 0;
807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return ParseParenExpr(Res, EndLoc) ||
808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman         ParseBinOpRHS(1, Res, EndLoc);
809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const MCExpr *Expr;
81319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc StartLoc = Lexer.getLoc();
815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseExpression(Expr))
816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!Expr->EvaluateAsAbsolute(Res))
819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Error(StartLoc, "expected absolute expression");
820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
82419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic unsigned getBinOpPrecedence(AsmToken::TokenKind K,
825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                   MCBinaryExpr::Opcode &Kind) {
826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  switch (K) {
827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  default:
828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return 0;    // not a binop.
829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Lowest Precedence: &&, ||
831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::AmpAmp:
832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Kind = MCBinaryExpr::LAnd;
833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return 1;
834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::PipePipe:
835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Kind = MCBinaryExpr::LOr;
836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return 1;
837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Low Precedence: |, &, ^
84019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //
84119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // FIXME: gas seems to support '!' as an infix operator?
84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::Pipe:
84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Kind = MCBinaryExpr::Or;
844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return 2;
84519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::Caret:
84619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Kind = MCBinaryExpr::Xor;
84719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 2;
84819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::Amp:
84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Kind = MCBinaryExpr::And;
850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return 2;
85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >=
853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::EqualEqual:
854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Kind = MCBinaryExpr::EQ;
85519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 3;
856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::ExclaimEqual:
857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::LessGreater:
858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Kind = MCBinaryExpr::NE;
85919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 3;
860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::Less:
861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Kind = MCBinaryExpr::LT;
86219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 3;
863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::LessEqual:
864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Kind = MCBinaryExpr::LTE;
86519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 3;
866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::Greater:
867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Kind = MCBinaryExpr::GT;
86819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 3;
869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::GreaterEqual:
870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Kind = MCBinaryExpr::GTE;
871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return 3;
872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
87319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Intermediate Precedence: <<, >>
874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::LessLess:
875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Kind = MCBinaryExpr::Shl;
876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return 4;
877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::GreaterGreater:
878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Kind = MCBinaryExpr::Shr;
879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return 4;
88019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
88119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // High Intermediate Precedence: +, -
88219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::Plus:
88319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Kind = MCBinaryExpr::Add;
88419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 5;
88519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::Minus:
88619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Kind = MCBinaryExpr::Sub;
88719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 5;
88819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
88919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Highest Precedence: *, /, %
89019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::Star:
89119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Kind = MCBinaryExpr::Mul;
89219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 6;
89319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::Slash:
89419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Kind = MCBinaryExpr::Div;
89519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 6;
89619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AsmToken::Percent:
89719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Kind = MCBinaryExpr::Mod;
89819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 6;
899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Res contains the LHS of the expression on input.
905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                              SMLoc &EndLoc) {
907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  while (1) {
908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
91019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // If the next token is lower precedence than we are allowed to eat, return
912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // successfully with what we ate already.
913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (TokPrec < Precedence)
914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return false;
91519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
91719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Eat the next primary expression.
919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    const MCExpr *RHS;
920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParsePrimaryExpr(RHS, EndLoc)) return true;
92119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // If BinOp binds less tightly with RHS than the operator after RHS, let
923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // the pending operator take RHS as its LHS.
924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MCBinaryExpr::Opcode Dummy;
925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (TokPrec < NextTokPrec) {
927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Merge LHS and RHS according to operator.
931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
93519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
93619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
93719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseStatement:
939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///   ::= EndOfStatement
940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///   ::= Label* Directive ...Operands... EndOfStatement
941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///   ::= Label* Identifier OperandList* EndOfStatement
942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseStatement() {
943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Lexer.is(AsmToken::EndOfStatement)) {
944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Out.AddBlankLine();
945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
94919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Statements always start with an identifier or are a full line comment.
950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  AsmToken ID = getTok();
951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc IDLoc = ID.getLoc();
952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringRef IDVal;
953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t LocalLabelVal = -1;
95419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // A full line comment is a '#' as the first token.
95519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Lexer.is(AsmToken::Hash))
95619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return ParseCppHashLineFilenameComment(IDLoc);
95719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
95819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Allow an integer followed by a ':' as a directional local label.
959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Lexer.is(AsmToken::Integer)) {
960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    LocalLabelVal = getTok().getIntVal();
961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (LocalLabelVal < 0) {
962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (!TheCondState.Ignore)
963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return TokError("unexpected token at start of statement");
964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      IDVal = "";
965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    else {
967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      IDVal = getTok().getString();
968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Lex(); // Consume the integer token to be used as an identifier token.
969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Lexer.getKind() != AsmToken::Colon) {
970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (!TheCondState.Ignore)
971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          return TokError("unexpected token at start of statement");
972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
97419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
97519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else if (Lexer.is(AsmToken::Dot)) {
97619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Treat '.' as a valid identifier in this context.
97719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lex();
97819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IDVal = ".";
97919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
98019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else if (ParseIdentifier(IDVal)) {
981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (!TheCondState.Ignore)
982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("unexpected token at start of statement");
983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    IDVal = "";
984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
98619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Handle conditional assembly here before checking for skipping.  We
988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // have to do this so that .endif isn't skipped in a ".if 0" block for
989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // example.
990894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (IDVal == ".if")
991894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return ParseDirectiveIf(IDLoc);
99219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IDVal == ".ifdef")
99319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return ParseDirectiveIfdef(IDLoc, true);
99419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IDVal == ".ifndef" || IDVal == ".ifnotdef")
99519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return ParseDirectiveIfdef(IDLoc, false);
996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (IDVal == ".elseif")
997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return ParseDirectiveElseIf(IDLoc);
998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (IDVal == ".else")
999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return ParseDirectiveElse(IDLoc);
1000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (IDVal == ".endif")
1001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return ParseDirectiveEndIf(IDLoc);
100219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // If we are in a ".if 0" block, ignore this statement.
1004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (TheCondState.Ignore) {
1005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EatToEndOfStatement();
1006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
1007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
100819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // FIXME: Recurse on local labels?
1010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // See what kind of statement we have.
1012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  switch (Lexer.getKind()) {
1013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::Colon: {
101419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CheckForValidSection();
101519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // identifier ':'   -> Label.
1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
1018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
101919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Diagnose attempt to use '.' as a label.
102019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".")
102119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
102219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Diagnose attempt to use a variable as a label.
1024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //
1025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // FIXME: Diagnostics. Note the location of the definition as a label.
1026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // FIXME: This doesn't diagnose assignment to a symbol which has been
1027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // implicitly marked as external.
1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MCSymbol *Sym;
1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (LocalLabelVal == -1)
1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Sym = getContext().GetOrCreateSymbol(IDVal);
1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    else
1032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (!Sym->isUndefined() || Sym->isVariable())
1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return Error(IDLoc, "invalid symbol redefinition");
103519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Emit the label.
1037894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Out.EmitLabel(Sym);
103819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Consume any end of statement token, if present, to avoid spurious
1040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // AddBlankLine calls().
1041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Lexer.is(AsmToken::EndOfStatement)) {
1042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Lex();
1043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Lexer.is(AsmToken::Eof))
1044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return false;
1045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return ParseStatement();
1048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case AsmToken::Equal:
1051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // identifier '=' ... -> assignment statement
1052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
105419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return ParseAssignment(IDVal, true);
1055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  default: // Normal instruction or directive.
1057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    break;
1058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // If macros are enabled, check to see if this is a macro instantiation.
1061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (MacrosEnabled)
1062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (const Macro *M = MacroMap.lookup(IDVal))
1063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return HandleMacroEntry(IDVal, IDLoc, M);
1064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
106519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Otherwise, we have a normal instruction or directive.
106619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IDVal[0] == '.' && IDVal != ".") {
1067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Assembler features
106819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".set" || IDVal == ".equ")
106919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveSet(IDVal, true);
107019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".equiv")
107119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveSet(IDVal, false);
1072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Data directives
1074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".ascii")
107619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveAscii(IDVal, false);
107719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".asciz" || IDVal == ".string")
107819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveAscii(IDVal, true);
1079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".byte")
1081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveValue(1);
1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".short")
1083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveValue(2);
108419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".value")
108519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveValue(2);
108619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".2byte")
108719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveValue(2);
1088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".long")
1089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveValue(4);
109019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".int")
109119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveValue(4);
109219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".4byte")
109319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveValue(4);
1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".quad")
1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveValue(8);
109619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".8byte")
109719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveValue(8);
109819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".single" || IDVal == ".float")
109919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveRealValue(APFloat::IEEEsingle);
110019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".double")
110119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveRealValue(APFloat::IEEEdouble);
1102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".align") {
1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
1105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveAlign(IsPow2, /*ExprSize=*/1);
1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".align32") {
1108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
1109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveAlign(IsPow2, /*ExprSize=*/4);
1110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".balign")
1112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
1113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".balignw")
1114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
1115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".balignl")
1116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
1117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".p2align")
1118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
1119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".p2alignw")
1120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
1121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".p2alignl")
1122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
1123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".org")
1125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveOrg();
1126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".fill")
1128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveFill();
112919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".space" || IDVal == ".skip")
1130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveSpace();
113119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".zero")
113219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveZero();
1133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Symbol attribute directives
1135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".globl" || IDVal == ".global")
1137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveSymbolAttribute(MCSA_Global);
1138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".indirect_symbol")
1139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
1140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".lazy_reference")
1141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
1142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".no_dead_strip")
1143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
114419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".symbol_resolver")
114519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver);
1146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".private_extern")
1147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
1148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".reference")
1149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveSymbolAttribute(MCSA_Reference);
1150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".weak_definition")
1151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition);
1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".weak_reference")
1153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
1154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".weak_def_can_be_hidden")
1155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
1156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
115719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".comm" || IDVal == ".common")
1158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveComm(/*IsLocal=*/false);
1159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".lcomm")
1160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveComm(/*IsLocal=*/true);
1161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".abort")
1163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveAbort();
1164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (IDVal == ".include")
1165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return ParseDirectiveInclude();
1166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
116719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IDVal == ".code16")
116819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TokError(Twine(IDVal) + " not supported yet");
116919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Look up the handler in the handler table.
1171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
1172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      DirectiveMap.lookup(IDVal);
1173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Handler.first)
1174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return (*Handler.second)(Handler.first, IDVal, IDLoc);
1175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Target hook for parsing target specific directives.
1177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (!getTargetParser().ParseDirective(ID))
1178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return false;
1179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
118019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool retval = Warning(IDLoc, "ignoring directive for now");
1181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EatToEndOfStatement();
118219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return retval;
1183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
118519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CheckForValidSection();
118619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Canonicalize the opcode to lower case.
1188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SmallString<128> Opcode;
1189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (unsigned i = 0, e = IDVal.size(); i != e; ++i)
1190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Opcode.push_back(tolower(IDVal[i]));
119119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
1193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc,
1194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                                     ParsedOperands);
1195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
119619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Dump the parsed representation, if requested.
119719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getShowParsedOperands()) {
119819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallString<256> Str;
119919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    raw_svector_ostream OS(Str);
120019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << "parsed instruction: [";
120119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (unsigned i = 0; i != ParsedOperands.size(); ++i) {
120219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (i != 0)
120319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        OS << ", ";
120419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ParsedOperands[i]->print(OS);
1205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
120619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << "]";
120719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
120819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PrintMessage(IDLoc, OS.str(), "note");
1209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
121119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If parsing succeeded, match the instruction.
1212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!HadError)
121319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, ParsedOperands,
121419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                         Out);
1215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Free any parsed operands.
1217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
1218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    delete ParsedOperands[i];
1219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
122019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Don't skip the rest of the line, the instruction parser is responsible for
122119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // that.
122219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
1223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
122519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// EatToEndOfLine uses the Lexer to eat the characters to the end of the line
122619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// since they may not be able to be tokenized to get to the end of line token.
122719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid AsmParser::EatToEndOfLine() {
122819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Lexer.is(AsmToken::EndOfStatement))
122919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lexer.LexUntilEndOfLine();
123019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Eat EOL.
123119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lex();
123219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
123319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
123419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseCppHashLineFilenameComment as this:
123519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///   ::= # number "filename"
123619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// or just as a full line comment if it doesn't have a number and a string.
123719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) {
123819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Lex(); // Eat the hash token.
123919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
124019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::Integer)) {
124119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Consume the line since in cases it is not a well-formed line directive,
124219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // as if were simply a full line comment.
124319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    EatToEndOfLine();
124419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
124519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
124619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
124719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t LineNumber = getTok().getIntVal();
124819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Lex();
124919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
125019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::String)) {
125119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    EatToEndOfLine();
125219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
125319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
125419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
125519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StringRef Filename = getTok().getString();
125619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Get rid of the enclosing quotes.
125719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Filename = Filename.substr(1, Filename.size()-2);
125819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
125919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Save the SMLoc, Filename and LineNumber for later use by diagnostics.
126019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CppHashLoc = L;
126119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CppHashFilename = Filename;
126219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CppHashLineNumber = LineNumber;
126319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
126419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Ignore any trailing characters, they're just comment.
126519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  EatToEndOfLine();
126619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
126719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
126819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
126919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// DiagHandler - will use the the last parsed cpp hash line filename comment
127019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// for the Filename and LineNo if any in the diagnostic.
127119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
127219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const AsmParser *Parser = static_cast<const AsmParser*>(Context);
127319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  raw_ostream &OS = errs();
127419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
127519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
127619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const SMLoc &DiagLoc = Diag.getLoc();
127719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
127819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc);
127919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
128019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Like SourceMgr::PrintMessage() we need to print the include stack if any
128119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // before printing the message.
128219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
128319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Parser->SavedDiagHandler && DiagCurBuffer > 0) {
128419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman     SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
128519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman     DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
128619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
128719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
128819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If we have not parsed a cpp hash line filename comment or the source
128919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // manager changed or buffer changed (like in a nested include) then just
129019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // print the normal diagnostic using its Filename and LineNo.
129119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Parser->CppHashLineNumber ||
129219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      &DiagSrcMgr != &Parser->SrcMgr ||
129319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DiagBuf != CppHashBuf) {
129419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Parser->SavedDiagHandler)
129519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
129619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
129719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Diag.Print(0, OS);
129819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return;
129919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
130019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
130119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Use the CppHashFilename and calculate a line number based on the
130219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for
130319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // the diagnostic.
130419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const std::string Filename = Parser->CppHashFilename;
130519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
130619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
130719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int CppHashLocLineNo =
130819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf);
130919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int LineNo = Parser->CppHashLineNumber - 1 +
131019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               (DiagLocLineNo - CppHashLocLineNo);
131119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
131219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SMDiagnostic NewDiag(*Diag.getSourceMgr(),
131319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       Diag.getLoc(),
131419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       Filename,
131519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       LineNo,
131619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       Diag.getColumnNo(),
131719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       Diag.getMessage(),
131819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       Diag.getLineContents(),
131919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       Diag.getShowLine());
132019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
132119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Parser->SavedDiagHandler)
132219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
132319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
132419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NewDiag.Print(0, OS);
132519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
132619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
132719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body,
132819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            const std::vector<StringRef> &Parameters,
132919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            const std::vector<std::vector<AsmToken> > &A,
133019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            const SMLoc &L) {
1331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  raw_svector_ostream OS(Buf);
133219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned NParameters = Parameters.size();
133319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (NParameters != 0 && NParameters != A.size())
133419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Error(L, "Wrong number of arguments");
1335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  while (!Body.empty()) {
1337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Scan for the next substitution.
1338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    std::size_t End = Body.size(), Pos = 0;
1339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    for (; Pos != End; ++Pos) {
1340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Check for a substitution or escape.
134119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!NParameters) {
134219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // This macro has no parameters, look for $0, $1, etc.
134319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Body[Pos] != '$' || Pos + 1 == End)
134419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          continue;
134519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
134619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        char Next = Body[Pos + 1];
134719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Next == '$' || Next == 'n' || isdigit(Next))
134819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
134919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      } else {
135019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // This macro has parameters, look for \foo, \bar, etc.
135119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Body[Pos] == '\\' && Pos + 1 != End)
135219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
135319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
1354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Add the prefix.
1357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    OS << Body.slice(0, Pos);
1358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Check if we reached the end.
1360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Pos == End)
1361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
1362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
136319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!NParameters) {
136419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (Body[Pos+1]) {
136519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // $$ => $
136619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case '$':
136719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        OS << '$';
136819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
1369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
137019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // $n => number of arguments
137119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case 'n':
137219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        OS << A.size();
137319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
1374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
137519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // $[0-9] => argument
137619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default: {
137719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Missing arguments are ignored.
137819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        unsigned Index = Body[Pos+1] - '0';
137919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Index >= A.size())
138019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
138119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
138219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Otherwise substitute with the token values, with spaces eliminated.
138319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        for (std::vector<AsmToken>::const_iterator it = A[Index].begin(),
138419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               ie = A[Index].end(); it != ie; ++it)
138519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          OS << it->getString();
1386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        break;
138719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
138819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
138919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Pos += 2;
139019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
139119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned I = Pos + 1;
139219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      while (isalnum(Body[I]) && I + 1 != End)
139319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        ++I;
139419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
139519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const char *Begin = Body.data() + Pos +1;
139619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      StringRef Argument(Begin, I - (Pos +1));
139719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned Index = 0;
139819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (; Index < NParameters; ++Index)
139919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Parameters[Index] == Argument)
140019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
140119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
140219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // FIXME: We should error at the macro definition.
140319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Index == NParameters)
140419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return Error(L, "Parameter not found");
1405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      for (std::vector<AsmToken>::const_iterator it = A[Index].begin(),
1407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman             ie = A[Index].end(); it != ie; ++it)
1408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        OS << it->getString();
1409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
141019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Pos += 1 + Argument.size();
141119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
1412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Update the scan point.
141319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Body = Body.substr(Pos);
1414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // We include the .endmacro in the buffer as our queue to exit the macro
1417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // instantiation.
1418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  OS << ".endmacro\n";
141919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
142019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
1421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
142219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL,
142319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       MemoryBuffer *I)
142419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitLoc(EL)
142519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{
1426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc,
1429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 const Macro *M) {
1430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
1431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // this, although we should protect against infinite loops.
1432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ActiveMacros.size() == 20)
1433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("macros cannot be nested more than 20 levels deep");
1434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Parse the macro instantiation arguments.
1436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  std::vector<std::vector<AsmToken> > MacroArguments;
1437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MacroArguments.push_back(std::vector<AsmToken>());
1438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned ParenLevel = 0;
1439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (;;) {
1440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Lexer.is(AsmToken::Eof))
1441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("unexpected token in macro instantiation");
1442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Lexer.is(AsmToken::EndOfStatement))
1443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
1444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // If we aren't inside parentheses and this is a comma, start a new token
1446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // list.
1447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) {
1448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      MacroArguments.push_back(std::vector<AsmToken>());
1449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else {
1450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Adjust the current parentheses level.
1451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Lexer.is(AsmToken::LParen))
1452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        ++ParenLevel;
1453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      else if (Lexer.is(AsmToken::RParen) && ParenLevel)
1454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        --ParenLevel;
1455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Append the token to the current argument list.
1457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      MacroArguments.back().push_back(getTok());
1458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
1460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
146219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Macro instantiation is lexical, unfortunately. We construct a new buffer
146319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // to hold the macro body with substitutions.
146419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallString<256> Buf;
146519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StringRef Body = M->Body;
146619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
146719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (expandMacro(Buf, Body, M->Parameters, MacroArguments, getTok().getLoc()))
146819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
146919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
147019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MemoryBuffer *Instantiation =
147119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MemoryBuffer::getMemBufferCopy(Buf.str(), "<instantiation>");
147219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Create the macro instantiation object and add to the current macro
1474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // instantiation stack.
1475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MacroInstantiation *MI = new MacroInstantiation(M, NameLoc,
1476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                                  getTok().getLoc(),
147719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                  Instantiation);
1478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ActiveMacros.push_back(MI);
1479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Jump to the macro instantiation and prime the lexer.
1481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc());
1482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
1483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
1484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
1486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid AsmParser::HandleMacroExit() {
1489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Jump to the EndOfStatement we should return to, and consume it.
1490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  JumpToLoc(ActiveMacros.back()->ExitLoc);
1491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
1492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Pop the instantiation entry.
1494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  delete ActiveMacros.back();
1495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ActiveMacros.pop_back();
1496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
149819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void MarkUsed(const MCExpr *Value) {
149919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (Value->getKind()) {
150019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Binary:
150119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MarkUsed(static_cast<const MCBinaryExpr*>(Value)->getLHS());
150219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MarkUsed(static_cast<const MCBinaryExpr*>(Value)->getRHS());
150319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
150419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Target:
150519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Constant:
150619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
150719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::SymbolRef: {
150819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static_cast<const MCSymbolRefExpr*>(Value)->getSymbol().setUsed(true);
150919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
151019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
151119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MCExpr::Unary:
151219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MarkUsed(static_cast<const MCUnaryExpr*>(Value)->getSubExpr());
151319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
151419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
151519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
151619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
151719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
1518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // FIXME: Use better location, we should use proper tokens.
1519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc EqualLoc = Lexer.getLoc();
1520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const MCExpr *Value;
1522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseExpression(Value))
1523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
152419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
152519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MarkUsed(Value);
152619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Lexer.isNot(AsmToken::EndOfStatement))
1528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in assignment");
1529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
153019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Error on assignment to '.'.
153119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Name == ".") {
153219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Error(EqualLoc, ("assignment to pseudo-symbol '.' is unsupported "
153319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            "(use '.space' or '.org').)"));
153419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
153519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Eat the end of statement marker.
1537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
1538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Validate that the LHS is allowed to be a variable (either it has not been
1540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // used as a symbol, or it is an absolute symbol).
1541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MCSymbol *Sym = getContext().LookupSymbol(Name);
1542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Sym) {
1543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Diagnose assignment to a label.
1544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //
1545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // FIXME: Diagnostics. Note the location of the definition as a label.
1546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // FIXME: Diagnose assignment to protected identifier (e.g., register name).
154719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
1548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      ; // Allow redefinitions of undefined symbols only used in directives.
154919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef))
1550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return Error(EqualLoc, "redefinition of '" + Name + "'");
1551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    else if (!Sym->isVariable())
1552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return Error(EqualLoc, "invalid assignment to '" + Name + "'");
1553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
1554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
1555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                   Name + "'");
155619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
155719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Don't count these checks as uses.
155819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Sym->setUsed(false);
1559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else
1560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Sym = getContext().GetOrCreateSymbol(Name);
1561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // FIXME: Handle '.'.
1563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Do the assignment.
1565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Out.EmitAssignment(Sym, Value);
1566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
1568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseIdentifier:
1571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///   ::= identifier
1572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///   ::= string
1573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseIdentifier(StringRef &Res) {
157419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // The assembler has relaxed rules for accepting identifiers, in particular we
157519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // allow things like '.globl $foo', which would normally be separate
157619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // tokens. At this level, we have already lexed so we cannot (currently)
157719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // handle this as a context dependent token, instead we detect adjacent tokens
157819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // and return the combined identifier.
157919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Lexer.is(AsmToken::Dollar)) {
158019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SMLoc DollarLoc = getLexer().getLoc();
158119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
158219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Consume the dollar sign, and check for a following identifier.
158319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lex();
158419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Lexer.isNot(AsmToken::Identifier))
158519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
158619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
158719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // We have a '$' followed by an identifier, make sure they are adjacent.
158819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
158919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
159019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
159119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Construct the joined identifier and consume the token.
159219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Res = StringRef(DollarLoc.getPointer(),
159319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                    getTok().getIdentifier().size() + 1);
159419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lex();
159519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
159619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
159719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
159819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Lexer.isNot(AsmToken::Identifier) &&
159919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Lexer.isNot(AsmToken::String))
160019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
1601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Res = getTok().getIdentifier();
1603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex(); // Consume the identifier token.
1605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
1607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveSet:
161019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///   ::= .equ identifier ',' expression
161119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///   ::= .equiv identifier ',' expression
1612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///   ::= .set identifier ',' expression
161319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) {
1614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringRef Name;
1615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseIdentifier(Name))
161719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("expected identifier after '" + Twine(IDVal) + "'");
161819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::Comma))
162019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("unexpected token in '" + Twine(IDVal) + "'");
1621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
1622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
162319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return ParseAssignment(Name, allow_redef);
1624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseEscapedString(std::string &Data) {
1627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  assert(getLexer().is(AsmToken::String) && "Unexpected current token!");
1628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Data = "";
1630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringRef Str = getTok().getStringContents();
1631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
1632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Str[i] != '\\') {
1633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Data += Str[i];
1634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      continue;
1635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Recognize escaped characters. Note that this escape semantics currently
1638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
1639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ++i;
1640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (i == e)
1641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("unexpected backslash at end of string");
1642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Recognize octal sequences.
1644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if ((unsigned) (Str[i] - '0') <= 7) {
1645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Consume up to three octal characters.
1646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      unsigned Value = Str[i] - '0';
1647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        ++i;
1650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Value = Value * 8 + (Str[i] - '0');
1651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          ++i;
1654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Value = Value * 8 + (Str[i] - '0');
1655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        }
1656894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
1657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Value > 255)
1659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return TokError("invalid octal escape sequence (out of range)");
1660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Data += (unsigned char) Value;
1662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      continue;
1663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Otherwise recognize individual escapes.
1666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    switch (Str[i]) {
1667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    default:
1668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Just reject invalid escape sequences for now.
1669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("invalid escape sequence (unrecognized character)");
1670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case 'b': Data += '\b'; break;
1672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case 'f': Data += '\f'; break;
1673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case 'n': Data += '\n'; break;
1674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case 'r': Data += '\r'; break;
1675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case 't': Data += '\t'; break;
1676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case '"': Data += '"'; break;
1677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case '\\': Data += '\\'; break;
1678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
1682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveAscii:
168519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///   ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
168619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
1687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement)) {
168819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CheckForValidSection();
168919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    for (;;) {
1691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (getLexer().isNot(AsmToken::String))
169219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return TokError("expected string in '" + Twine(IDVal) + "' directive");
1693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      std::string Data;
1695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (ParseEscapedString(Data))
1696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return true;
1697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      getStreamer().EmitBytes(Data, DEFAULT_ADDRSPACE);
1699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (ZeroTerminated)
1700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        getStreamer().EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
1701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Lex();
1703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (getLexer().is(AsmToken::EndOfStatement))
1705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        break;
1706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (getLexer().isNot(AsmToken::Comma))
170819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
1709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Lex();
1710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
1714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
1715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveValue
1718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  ::= (.byte | .short | ... ) [ expression (, expression)* ]
1719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveValue(unsigned Size) {
1720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement)) {
172119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CheckForValidSection();
172219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    for (;;) {
1724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      const MCExpr *Value;
172519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SMLoc ExprLoc = getLexer().getLoc();
1726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (ParseExpression(Value))
1727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return true;
1728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Special case constant expressions to match code generator.
173019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
173119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        assert(Size <= 8 && "Invalid size");
173219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        uint64_t IntValue = MCE->getValue();
173319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
173419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return Error(ExprLoc, "literal value out of range for directive");
173519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        getStreamer().EmitIntValue(IntValue, Size, DEFAULT_ADDRSPACE);
173619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      } else
1737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        getStreamer().EmitValue(Value, Size, DEFAULT_ADDRSPACE);
1738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (getLexer().is(AsmToken::EndOfStatement))
1740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        break;
174119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // FIXME: Improve diagnostic.
1743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (getLexer().isNot(AsmToken::Comma))
1744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return TokError("unexpected token in directive");
1745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Lex();
1746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
1750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
1751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
175319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveRealValue
175419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///  ::= (.single | .double) [ expression (, expression)* ]
175519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) {
175619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement)) {
175719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CheckForValidSection();
175819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
175919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (;;) {
176019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // We don't truly support arithmetic on floating point expressions, so we
176119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // have to manually parse unary prefixes.
176219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool IsNeg = false;
176319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (getLexer().is(AsmToken::Minus)) {
176419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Lex();
176519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        IsNeg = true;
176619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      } else if (getLexer().is(AsmToken::Plus))
176719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Lex();
176819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
176919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (getLexer().isNot(AsmToken::Integer) &&
177019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          getLexer().isNot(AsmToken::Real) &&
177119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          getLexer().isNot(AsmToken::Identifier))
177219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return TokError("unexpected token in directive");
177319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
177419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Convert to an APFloat.
177519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      APFloat Value(Semantics);
177619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      StringRef IDVal = getTok().getString();
177719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (getLexer().is(AsmToken::Identifier)) {
177819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf"))
177919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Value = APFloat::getInf(Semantics);
178019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        else if (!IDVal.compare_lower("nan"))
178119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Value = APFloat::getNaN(Semantics, false, ~0);
178219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        else
178319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return TokError("invalid floating point literal");
178419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
178519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          APFloat::opInvalidOp)
178619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return TokError("invalid floating point literal");
178719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (IsNeg)
178819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Value.changeSign();
178919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
179019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Consume the numeric token.
179119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Lex();
179219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
179319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Emit the value as an integer.
179419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      APInt AsInt = Value.bitcastToAPInt();
179519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      getStreamer().EmitIntValue(AsInt.getLimitedValue(),
179619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 AsInt.getBitWidth() / 8, DEFAULT_ADDRSPACE);
179719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
179819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (getLexer().is(AsmToken::EndOfStatement))
179919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
180019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
180119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (getLexer().isNot(AsmToken::Comma))
180219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return TokError("unexpected token in directive");
180319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Lex();
180419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
180519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
180619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
180719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Lex();
180819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
180919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
181019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveSpace
1812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  ::= .space expression [ , expression ]
1813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveSpace() {
181419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CheckForValidSection();
181519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t NumBytes;
1817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseAbsoluteExpression(NumBytes))
1818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
1819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t FillExpr = 0;
1821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().isNot(AsmToken::Comma))
1823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("unexpected token in '.space' directive");
1824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
182519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParseAbsoluteExpression(FillExpr))
1827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
1828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().isNot(AsmToken::EndOfStatement))
1830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("unexpected token in '.space' directive");
1831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
1834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (NumBytes <= 0)
1836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("invalid number of bytes in '.space' directive");
1837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
1839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  getStreamer().EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
1840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
1842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
184419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveZero
184519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///  ::= .zero expression
184619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool AsmParser::ParseDirectiveZero() {
184719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CheckForValidSection();
184819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
184919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t NumBytes;
185019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ParseAbsoluteExpression(NumBytes))
185119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
185219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
185319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Val = 0;
185419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().is(AsmToken::Comma)) {
185519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lex();
185619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (ParseAbsoluteExpression(Val))
185719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
185819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
185919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
186019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
186119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("unexpected token in '.zero' directive");
186219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
186319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Lex();
186419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
186519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitFill(NumBytes, Val, DEFAULT_ADDRSPACE);
186619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
186719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
186819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
186919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveFill
1871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  ::= .fill expression , expression , expression
1872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveFill() {
187319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CheckForValidSection();
187419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t NumValues;
1876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseAbsoluteExpression(NumValues))
1877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
1878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::Comma))
1880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.fill' directive");
1881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
188219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t FillSize;
1884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseAbsoluteExpression(FillSize))
1885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
1886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::Comma))
1888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.fill' directive");
1889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
189019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t FillExpr;
1892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseAbsoluteExpression(FillExpr))
1893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
1894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
1896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.fill' directive");
189719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
1899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
1901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
1902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (uint64_t i = 0, e = NumValues; i != e; ++i)
1904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    getStreamer().EmitIntValue(FillExpr, FillSize, DEFAULT_ADDRSPACE);
1905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
1907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveOrg
1910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  ::= .org expression [ , expression ]
1911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveOrg() {
191219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CheckForValidSection();
191319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const MCExpr *Offset;
1915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseExpression(Offset))
1916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
1917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Parse optional fill expression.
1919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t FillExpr = 0;
1920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().isNot(AsmToken::Comma))
1922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("unexpected token in '.org' directive");
1923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
192419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParseAbsoluteExpression(FillExpr))
1926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
1927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().isNot(AsmToken::EndOfStatement))
1929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("unexpected token in '.org' directive");
1930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
1933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // FIXME: Only limited forms of relocatable expressions are accepted here, it
1935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // has to be relative to the current section.
1936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  getStreamer().EmitValueToOffset(Offset, FillExpr);
1937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
1939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveAlign
1942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  ::= {.align, ...} expression [ , expression [ , expression ]]
1943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
194419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CheckForValidSection();
194519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc AlignmentLoc = getLexer().getLoc();
1947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t Alignment;
1948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseAbsoluteExpression(Alignment))
1949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
1950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc MaxBytesLoc;
1952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool HasFillExpr = false;
1953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t FillExpr = 0;
1954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t MaxBytesToFill = 0;
1955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().isNot(AsmToken::Comma))
1957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("unexpected token in directive");
1958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
1959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // The fill expression can be omitted while specifying a maximum number of
1961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // alignment bytes, e.g:
1962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //  .align 3,,4
1963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().isNot(AsmToken::Comma)) {
1964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      HasFillExpr = true;
1965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (ParseAbsoluteExpression(FillExpr))
1966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return true;
1967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().isNot(AsmToken::EndOfStatement)) {
1970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (getLexer().isNot(AsmToken::Comma))
1971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return TokError("unexpected token in directive");
1972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Lex();
1973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      MaxBytesLoc = getLexer().getLoc();
1975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (ParseAbsoluteExpression(MaxBytesToFill))
1976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return true;
197719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1978894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (getLexer().isNot(AsmToken::EndOfStatement))
1979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return TokError("unexpected token in directive");
1980894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
1984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!HasFillExpr)
1986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    FillExpr = 0;
1987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Compute alignment in bytes.
1989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (IsPow2) {
1990894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // FIXME: Diagnose overflow.
1991894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Alignment >= 32) {
1992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Error(AlignmentLoc, "invalid alignment value");
1993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Alignment = 31;
1994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Alignment = 1ULL << Alignment;
1997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Diagnose non-sensical max bytes to align.
2000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (MaxBytesLoc.isValid()) {
2001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (MaxBytesToFill < 1) {
2002894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
2003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            "many bytes, ignoring maximum bytes expression");
2004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      MaxBytesToFill = 0;
2005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
2006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (MaxBytesToFill >= Alignment) {
2008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
2009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman              "has no effect");
2010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      MaxBytesToFill = 0;
2011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
2012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Check whether we should use optimal code alignment for this .align
2015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // directive.
201619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool UseCodeAlign = getStreamer().getCurrentSection()->UseCodeAlign();
2017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
2018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      ValueSize == 1 && UseCodeAlign) {
2019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill);
2020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else {
2021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // FIXME: Target specific behavior about how the "extra" bytes are filled.
2022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize,
2023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                       MaxBytesToFill);
2024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveSymbolAttribute
2030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
2031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
2032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    for (;;) {
2034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      StringRef Name;
203519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SMLoc Loc = getTok().getLoc();
2036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2037894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (ParseIdentifier(Name))
203819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return Error(Loc, "expected identifier in directive");
203919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
204219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Assembler local symbols don't make any sense here. Complain loudly.
204319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Sym->isTemporary())
204419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return Error(Loc, "non-local symbol required in directive");
204519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      getStreamer().EmitSymbolAttribute(Sym, Attr);
2047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (getLexer().is(AsmToken::EndOfStatement))
2049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        break;
2050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (getLexer().isNot(AsmToken::Comma))
2052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return TokError("unexpected token in directive");
2053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Lex();
2054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
2055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
2058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveComm
2062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
2063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveComm(bool IsLocal) {
206419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CheckForValidSection();
206519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc IDLoc = getLexer().getLoc();
2067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringRef Name;
2068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseIdentifier(Name))
2069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("expected identifier in directive");
207019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Handle the identifier as the key symbol.
2072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::Comma))
2075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in directive");
2076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
2077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t Size;
2079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc SizeLoc = getLexer().getLoc();
2080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ParseAbsoluteExpression(Size))
2081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
2082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t Pow2Alignment = 0;
2084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc Pow2AlignmentLoc;
2085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().is(AsmToken::Comma)) {
2086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
2087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Pow2AlignmentLoc = getLexer().getLoc();
2088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParseAbsoluteExpression(Pow2Alignment))
2089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
209019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // If this target takes alignments in bytes (not log) validate and convert.
2092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Lexer.getMAI().getAlignmentIsInBytes()) {
2093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (!isPowerOf2_64(Pow2Alignment))
2094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
2095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Pow2Alignment = Log2_64(Pow2Alignment);
2096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
2097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
209819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
2100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.comm' or '.lcomm' directive");
210119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
2103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // NOTE: a size of zero for a .comm should create a undefined symbol
2105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // but a size of .lcomm creates a bss symbol of size zero.
2106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Size < 0)
2107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
2108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                 "be less than zero");
2109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // NOTE: The alignment in the directive is a power of 2 value, the assembler
2111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // may internally end up wanting an alignment in bytes.
2112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // FIXME: Diagnose overflow.
2113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Pow2Alignment < 0)
2114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
2115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                 "alignment, can't be less than zero");
2116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!Sym->isUndefined())
2118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Error(IDLoc, "invalid symbol redefinition");
2119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // '.lcomm' is equivalent to '.zerofill'.
2121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Create the Symbol as a common or local common with Size and Pow2Alignment
2122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (IsLocal) {
2123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    getStreamer().EmitZerofill(Ctx.getMachOSection(
2124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 "__DATA", "__bss", MCSectionMachO::S_ZEROFILL,
2125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 0, SectionKind::getBSS()),
2126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               Sym, Size, 1 << Pow2Alignment);
2127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
2128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
2131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveAbort
2135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  ::= .abort [... message ...]
2136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveAbort() {
2137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // FIXME: Use loc from directive.
2138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc Loc = getLexer().getLoc();
2139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringRef Str = ParseStringToEndOfStatement();
2141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
2142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.abort' directive");
2143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
2145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Str.empty())
2147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Error(Loc, ".abort detected. Assembly stopping.");
2148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  else
2149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
2150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // FIXME: Actually abort assembly here.
2151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveInclude
2156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///  ::= .include "filename"
2157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveInclude() {
2158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::String))
2159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("expected string in '.include' directive");
216019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  std::string Filename = getTok().getString();
2162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc IncludeLoc = getLexer().getLoc();
2163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
2164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
2166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.include' directive");
216719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Strip the quotes.
2169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Filename = Filename.substr(1, Filename.size()-2);
217019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Attempt to switch the lexer to the included file before consuming the end
2172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // of statement to avoid losing it when we switch.
2173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (EnterIncludeFile(Filename)) {
2174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Error(IncludeLoc, "Could not find include file '" + Filename + "'");
2175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
2176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveIf
2182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ::= .if expression
2183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
2184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  TheCondStack.push_back(TheCondState);
2185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  TheCondState.TheCond = AsmCond::IfCond;
2186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if(TheCondState.Ignore) {
2187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EatToEndOfStatement();
2188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  else {
2190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    int64_t ExprValue;
2191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParseAbsoluteExpression(ExprValue))
2192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
2193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().isNot(AsmToken::EndOfStatement))
2195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("unexpected token in '.if' directive");
219619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
2198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    TheCondState.CondMet = ExprValue;
2200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    TheCondState.Ignore = !TheCondState.CondMet;
2201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
220619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
220719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StringRef Name;
220819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TheCondStack.push_back(TheCondState);
220919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TheCondState.TheCond = AsmCond::IfCond;
221019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
221119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TheCondState.Ignore) {
221219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    EatToEndOfStatement();
221319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
221419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (ParseIdentifier(Name))
221519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TokError("expected identifier after '.ifdef'");
221619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
221719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lex();
221819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
221919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbol *Sym = getContext().LookupSymbol(Name);
222019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
222119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (expect_defined)
222219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      TheCondState.CondMet = (Sym != NULL && !Sym->isUndefined());
222319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
222419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      TheCondState.CondMet = (Sym == NULL || Sym->isUndefined());
222519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    TheCondState.Ignore = !TheCondState.CondMet;
222619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
222719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
222819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
222919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
223019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveElseIf
2232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ::= .elseif expression
2233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
2234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (TheCondState.TheCond != AsmCond::IfCond &&
2235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      TheCondState.TheCond != AsmCond::ElseIfCond)
2236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
2237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                          " an .elseif");
2238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  TheCondState.TheCond = AsmCond::ElseIfCond;
2239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool LastIgnoreState = false;
2241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!TheCondStack.empty())
2242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      LastIgnoreState = TheCondStack.back().Ignore;
2243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (LastIgnoreState || TheCondState.CondMet) {
2244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    TheCondState.Ignore = true;
2245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EatToEndOfStatement();
2246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  else {
2248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    int64_t ExprValue;
2249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ParseAbsoluteExpression(ExprValue))
2250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
2251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().isNot(AsmToken::EndOfStatement))
2253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("unexpected token in '.elseif' directive");
225419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
2256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    TheCondState.CondMet = ExprValue;
2257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    TheCondState.Ignore = !TheCondState.CondMet;
2258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveElse
2264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ::= .else
2265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
2266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
2267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.else' directive");
226819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
2270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (TheCondState.TheCond != AsmCond::IfCond &&
2272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      TheCondState.TheCond != AsmCond::ElseIfCond)
2273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
2274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                          ".elseif");
2275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  TheCondState.TheCond = AsmCond::ElseCond;
2276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool LastIgnoreState = false;
2277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!TheCondStack.empty())
2278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    LastIgnoreState = TheCondStack.back().Ignore;
2279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (LastIgnoreState || TheCondState.CondMet)
2280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    TheCondState.Ignore = true;
2281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  else
2282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    TheCondState.Ignore = false;
2283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveEndIf
2288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ::= .endif
2289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
2290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
2291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.endif' directive");
229219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
2294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if ((TheCondState.TheCond == AsmCond::NoCond) ||
2296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      TheCondStack.empty())
2297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
2298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                        ".else");
2299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!TheCondStack.empty()) {
2300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    TheCondState = TheCondStack.back();
2301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    TheCondStack.pop_back();
2302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveFile
2308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ::= .file [number] string
2309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
2310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // FIXME: I'm not sure what this is.
2311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t FileNumber = -1;
2312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SMLoc FileNumberLoc = getLexer().getLoc();
2313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().is(AsmToken::Integer)) {
2314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    FileNumber = getTok().getIntVal();
2315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
2316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (FileNumber < 1)
2318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("file number less than one");
2319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::String))
2322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.file' directive");
2323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringRef Filename = getTok().getString();
2325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Filename = Filename.substr(1, Filename.size()-2);
2326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
2327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
2329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.file' directive");
2330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (FileNumber == -1)
2332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    getStreamer().EmitFileDirective(Filename);
2333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  else {
233419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (getStreamer().EmitDwarfFileDirective(FileNumber, Filename))
233519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Error(FileNumberLoc, "file number already allocated");
2336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveLine
2342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ::= .line [number]
2343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
2344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().isNot(AsmToken::Integer))
2346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return TokError("unexpected token in '.line' directive");
2347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    int64_t LineNumber = getTok().getIntVal();
2349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    (void) LineNumber;
2350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
2351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // FIXME: Do something with the .line.
2353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
2356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.line' directive");
2357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveLoc
236319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
236419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///                                [epilogue_begin] [is_stmt VALUE] [isa VALUE]
236519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// The first number is a file number, must have been previously assigned with
236619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// a .file directive, the second number is the line number and optionally the
236719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// third number is a column position (zero if not specified).  The remaining
236819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// optional items are .loc sub-directives.
2369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
237019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::Integer))
2372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.loc' directive");
2373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int64_t FileNumber = getTok().getIntVal();
237419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (FileNumber < 1)
237519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("file number less than one in '.loc' directive");
237619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!getContext().isValidDwarfFileNumber(FileNumber))
237719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("unassigned file number in '.loc' directive");
2378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
2379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
238019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t LineNumber = 0;
238119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().is(AsmToken::Integer)) {
238219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LineNumber = getTok().getIntVal();
238319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (LineNumber < 1)
238419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TokError("line number less than one in '.loc' directive");
2385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Lex();
238619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
2387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
238819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t ColumnPos = 0;
238919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().is(AsmToken::Integer)) {
239019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ColumnPos = getTok().getIntVal();
239119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (ColumnPos < 0)
239219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TokError("column position less than zero in '.loc' directive");
239319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lex();
239419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
239519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
239619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
239719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Isa = 0;
239819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Discriminator = 0;
239919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement)) {
240019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (;;) {
240119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (getLexer().is(AsmToken::EndOfStatement))
240219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
240319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
240419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      StringRef Name;
240519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SMLoc Loc = getTok().getLoc();
240619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (getParser().ParseIdentifier(Name))
2407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return TokError("unexpected token in '.loc' directive");
2408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
240919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Name == "basic_block")
241019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Flags |= DWARF2_FLAG_BASIC_BLOCK;
241119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else if (Name == "prologue_end")
241219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Flags |= DWARF2_FLAG_PROLOGUE_END;
241319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else if (Name == "epilogue_begin")
241419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
241519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else if (Name == "is_stmt") {
241619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        SMLoc Loc = getTok().getLoc();
241719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        const MCExpr *Value;
241819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (getParser().ParseExpression(Value))
241919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return true;
242019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // The expression must be the constant 0 or 1.
242119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
242219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          int Value = MCE->getValue();
242319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (Value == 0)
242419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Flags &= ~DWARF2_FLAG_IS_STMT;
242519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          else if (Value == 1)
242619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Flags |= DWARF2_FLAG_IS_STMT;
242719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          else
242819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            return Error(Loc, "is_stmt value not 0 or 1");
242919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
243019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        else {
243119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return Error(Loc, "is_stmt value not the constant value of 0 or 1");
243219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
243319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
243419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else if (Name == "isa") {
243519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        SMLoc Loc = getTok().getLoc();
243619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        const MCExpr *Value;
243719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (getParser().ParseExpression(Value))
243819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return true;
243919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // The expression must be a constant greater or equal to 0.
244019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
244119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          int Value = MCE->getValue();
244219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (Value < 0)
244319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            return Error(Loc, "isa number less than zero");
244419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Isa = Value;
244519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
244619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        else {
244719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return Error(Loc, "isa number not a constant value");
244819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
244919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
245019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else if (Name == "discriminator") {
245119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (getParser().ParseAbsoluteExpression(Discriminator))
245219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return true;
245319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
245419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else {
245519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return Error(Loc, "unknown sub-directive in '.loc' directive");
245619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
2457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
245819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (getLexer().is(AsmToken::EndOfStatement))
245919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
2460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
2461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
246319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
246419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      Isa, Discriminator, StringRef());
246519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
246619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
246719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
246819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
246919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveStabs
247019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .stabs string, number, number, number
247119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveStabs(StringRef Directive,
247219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           SMLoc DirectiveLoc) {
247319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return TokError("unsupported directive '" + Directive + "'");
247419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
247519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
247619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFISections
247719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_sections section [, section]
247819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFISections(StringRef,
247919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                 SMLoc DirectiveLoc) {
248019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StringRef Name;
248119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool EH = false;
248219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool Debug = false;
248319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
248419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getParser().ParseIdentifier(Name))
248519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("Expected an identifier");
248619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
248719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Name == ".eh_frame")
248819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    EH = true;
248919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else if (Name == ".debug_frame")
249019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Debug = true;
249119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
249219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().is(AsmToken::Comma)) {
249319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Lex();
249419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
249519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (getParser().ParseIdentifier(Name))
249619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TokError("Expected an identifier");
249719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
249819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Name == ".eh_frame")
249919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      EH = true;
250019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else if (Name == ".debug_frame")
250119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Debug = true;
250219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
250319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
250419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFISections(EH, Debug);
250519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
250619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
250719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
250819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
250919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFIStartProc
251019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_startproc
251119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFIStartProc(StringRef,
251219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                  SMLoc DirectiveLoc) {
251319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFIStartProc();
251419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
251519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
251619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
251719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFIEndProc
251819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_endproc
251919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc) {
252019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFIEndProc();
252119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
252219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
252319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
252419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseRegisterOrRegisterNumber - parse register name or number.
252519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseRegisterOrRegisterNumber(int64_t &Register,
252619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                     SMLoc DirectiveLoc) {
252719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned RegNo;
252819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
252919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::Integer)) {
253019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (getParser().getTargetParser().ParseRegister(RegNo, DirectiveLoc,
253119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DirectiveLoc))
253219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
253319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Register = getContext().getRegisterInfo().getDwarfRegNum(RegNo, true);
253419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else
253519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return getParser().ParseAbsoluteExpression(Register);
253619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
253719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
253819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
253919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
254019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFIDefCfa
254119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_def_cfa register,  offset
254219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef,
254319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               SMLoc DirectiveLoc) {
254419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Register = 0;
254519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
254619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
254719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
254819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::Comma))
254919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("unexpected token in directive");
255019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Lex();
255119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
255219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Offset = 0;
255319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getParser().ParseAbsoluteExpression(Offset))
255419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
255519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
255619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFIDefCfa(Register, Offset);
255719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
255819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
255919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
256019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFIDefCfaOffset
256119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_def_cfa_offset offset
256219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef,
256319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                     SMLoc DirectiveLoc) {
256419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Offset = 0;
256519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getParser().ParseAbsoluteExpression(Offset))
256619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
256719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
256819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFIDefCfaOffset(Offset);
256919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
257019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
257119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
257219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFIAdjustCfaOffset
257319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_adjust_cfa_offset adjustment
257419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset(StringRef,
257519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                        SMLoc DirectiveLoc) {
257619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Adjustment = 0;
257719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getParser().ParseAbsoluteExpression(Adjustment))
257819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
257919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
258019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFIAdjustCfaOffset(Adjustment);
258119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
258219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
258319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
258419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFIDefCfaRegister
258519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_def_cfa_register register
258619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFIDefCfaRegister(StringRef,
258719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                       SMLoc DirectiveLoc) {
258819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Register = 0;
258919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
259019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
259119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
259219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFIDefCfaRegister(Register);
259319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
259419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
259519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
259619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFIOffset
259719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_offset register, offset
259819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc) {
259919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Register = 0;
260019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Offset = 0;
260119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
260219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
260319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
260419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
260519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::Comma))
260619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("unexpected token in directive");
260719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Lex();
260819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
260919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getParser().ParseAbsoluteExpression(Offset))
261019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
261119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
261219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFIOffset(Register, Offset);
261319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
261419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
261519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
261619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFIRelOffset
261719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_rel_offset register, offset
261819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFIRelOffset(StringRef,
261919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                  SMLoc DirectiveLoc) {
262019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Register = 0;
262119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
262219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
262319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
262419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
262519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::Comma))
262619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("unexpected token in directive");
262719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Lex();
262819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
262919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Offset = 0;
263019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getParser().ParseAbsoluteExpression(Offset))
263119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
263219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
263319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFIRelOffset(Register, Offset);
263419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
263519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
263619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
263719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool isValidEncoding(int64_t Encoding) {
263819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Encoding & ~0xff)
263919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
264019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
264119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Encoding == dwarf::DW_EH_PE_omit)
264219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
264319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
264419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const unsigned Format = Encoding & 0xf;
264519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
264619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
264719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
264819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
264919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
265019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
265119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const unsigned Application = Encoding & 0x70;
265219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Application != dwarf::DW_EH_PE_absptr &&
265319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Application != dwarf::DW_EH_PE_pcrel)
265419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
265519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
265619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
265719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
265819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
265919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFIPersonalityOrLsda
266019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_personality encoding, [symbol_name]
266119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_lsda encoding, [symbol_name]
266219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal,
266319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                    SMLoc DirectiveLoc) {
266419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Encoding = 0;
266519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getParser().ParseAbsoluteExpression(Encoding))
266619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
266719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Encoding == dwarf::DW_EH_PE_omit)
266819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
266919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
267019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!isValidEncoding(Encoding))
267119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("unsupported encoding.");
267219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
267319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::Comma))
267419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("unexpected token in directive");
267519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Lex();
267619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
267719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StringRef Name;
267819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getParser().ParseIdentifier(Name))
267919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("expected identifier in directive");
268019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
268119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
268219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
268319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IDVal == ".cfi_personality")
268419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getStreamer().EmitCFIPersonality(Sym, Encoding);
268519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else {
268619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(IDVal == ".cfi_lsda");
268719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getStreamer().EmitCFILsda(Sym, Encoding);
268819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
268919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
269019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
269119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
269219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFIRememberState
269319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_remember_state
269419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFIRememberState(StringRef IDVal,
269519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                      SMLoc DirectiveLoc) {
269619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFIRememberState();
269719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
269819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
269919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
270019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFIRestoreState
270119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_remember_state
270219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFIRestoreState(StringRef IDVal,
270319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                     SMLoc DirectiveLoc) {
270419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFIRestoreState();
270519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
270619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
270719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
270819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ParseDirectiveCFISameValue
270919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .cfi_same_value register
271019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveCFISameValue(StringRef IDVal,
271119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                  SMLoc DirectiveLoc) {
271219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t Register = 0;
271319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
271419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
271519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
271619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
271719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getStreamer().EmitCFISameValue(Register);
2718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveMacrosOnOff
2723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ::= .macros_on
2724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ::= .macros_off
2725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool GenericAsmParser::ParseDirectiveMacrosOnOff(StringRef Directive,
2726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                                 SMLoc DirectiveLoc) {
2727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
2728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Error(getLexer().getLoc(),
2729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                 "unexpected token in '" + Directive + "' directive");
2730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  getParser().MacrosEnabled = Directive == ".macros_on";
2732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveMacro
273719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ::= .macro name [parameters]
2738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool GenericAsmParser::ParseDirectiveMacro(StringRef Directive,
2739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                           SMLoc DirectiveLoc) {
2740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringRef Name;
2741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getParser().ParseIdentifier(Name))
2742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("expected identifier in directive");
2743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
274419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::vector<StringRef> Parameters;
274519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement)) {
274619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for(;;) {
274719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      StringRef Parameter;
274819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (getParser().ParseIdentifier(Parameter))
274919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return TokError("expected identifier in directive");
275019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Parameters.push_back(Parameter);
275119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
275219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (getLexer().isNot(AsmToken::Comma))
275319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
275419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Lex();
275519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
275619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
275719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
2759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '.macro' directive");
2760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Eat the end of statement.
2762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Lex();
2763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  AsmToken EndToken, StartToken = getTok();
2765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Lex the macro definition.
2767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (;;) {
2768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Check whether we have reached the end of the file.
2769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().is(AsmToken::Eof))
2770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return Error(DirectiveLoc, "no matching '.endmacro' in definition");
2771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Otherwise, check whether we have reach the .endmacro.
2773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (getLexer().is(AsmToken::Identifier) &&
2774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        (getTok().getIdentifier() == ".endm" ||
2775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman         getTok().getIdentifier() == ".endmacro")) {
2776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      EndToken = getTok();
2777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Lex();
2778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (getLexer().isNot(AsmToken::EndOfStatement))
2779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return TokError("unexpected token in '" + EndToken.getIdentifier() +
2780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                        "' directive");
2781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
2782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
2783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Otherwise, scan til the end of the statement.
2785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    getParser().EatToEndOfStatement();
2786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getParser().MacroMap.lookup(Name)) {
2789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
2790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const char *BodyStart = StartToken.getLoc().getPointer();
2793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const char *BodyEnd = EndToken.getLoc().getPointer();
2794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
279519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getParser().MacroMap[Name] = new Macro(Name, Body, Parameters);
2796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
2797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseDirectiveEndMacro
2800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ::= .endm
2801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ::= .endmacro
2802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive,
2803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                           SMLoc DirectiveLoc) {
2804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
2805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return TokError("unexpected token in '" + Directive + "' directive");
2806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // If we are inside a macro instantiation, terminate the current
2808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // instantiation.
2809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!getParser().ActiveMacros.empty()) {
2810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    getParser().HandleMacroExit();
2811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
2812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
2813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Otherwise, this .endmacro is a stray entry in the file; well formed
2815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // .endmacro directives are handled during the macro definition parsing.
2816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return TokError("unexpected '" + Directive + "' in file, "
2817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                  "no current macro definition");
2818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
282019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) {
282119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getParser().CheckForValidSection();
282219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
282319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCExpr *Value;
282419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
282519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getParser().ParseExpression(Value))
282619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
282719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
282819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getLexer().isNot(AsmToken::EndOfStatement))
282919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return TokError("unexpected token in directive");
283019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
283119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (DirName[1] == 's')
283219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getStreamer().EmitSLEB128Value(Value);
283319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
283419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getStreamer().EmitULEB128Value(Value);
283519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
283619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
283719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
283819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
283919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// \brief Create an MCAsmParser instance.
284119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMCAsmParser *llvm::createMCAsmParser(SourceMgr &SM,
2842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                     MCContext &C, MCStreamer &Out,
2843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                     const MCAsmInfo &MAI) {
284419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return new AsmParser(SM, C, Out, MAI);
2845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
2846