1//===- llvm/MC/MCAsmParser.h - Abstract Asm Parser Interface ----*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_MC_MCPARSER_MCASMPARSER_H
11#define LLVM_MC_MCPARSER_MCASMPARSER_H
12
13#include "llvm/ADT/None.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/SmallString.h"
16#include "llvm/ADT/SmallVector.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/Twine.h"
19#include "llvm/MC/MCParser/MCAsmLexer.h"
20#include "llvm/Support/SMLoc.h"
21#include <cstdint>
22#include <string>
23#include <utility>
24
25namespace llvm {
26
27class MCAsmInfo;
28class MCAsmParserExtension;
29class MCContext;
30class MCExpr;
31class MCInstPrinter;
32class MCInstrInfo;
33class MCStreamer;
34class MCTargetAsmParser;
35class SourceMgr;
36
37class InlineAsmIdentifierInfo {
38public:
39  void *OpDecl;
40  bool IsVarDecl;
41  unsigned Length, Size, Type;
42
43  void clear() {
44    OpDecl = nullptr;
45    IsVarDecl = false;
46    Length = 1;
47    Size = 0;
48    Type = 0;
49  }
50};
51
52/// \brief Generic Sema callback for assembly parser.
53class MCAsmParserSemaCallback {
54public:
55  virtual ~MCAsmParserSemaCallback();
56
57  virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf,
58                                          InlineAsmIdentifierInfo &Info,
59                                          bool IsUnevaluatedContext) = 0;
60  virtual StringRef LookupInlineAsmLabel(StringRef Identifier, SourceMgr &SM,
61                                         SMLoc Location, bool Create) = 0;
62  virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
63                                    unsigned &Offset) = 0;
64};
65
66/// \brief Generic assembler parser interface, for use by target specific
67/// assembly parsers.
68class MCAsmParser {
69public:
70  using DirectiveHandler = bool (*)(MCAsmParserExtension*, StringRef, SMLoc);
71  using ExtensionDirectiveHandler =
72      std::pair<MCAsmParserExtension*, DirectiveHandler>;
73
74  struct MCPendingError {
75    SMLoc Loc;
76    SmallString<64> Msg;
77    SMRange Range;
78  };
79
80private:
81  MCTargetAsmParser *TargetParser = nullptr;
82
83  unsigned ShowParsedOperands : 1;
84
85protected: // Can only create subclasses.
86  MCAsmParser();
87
88  bool HadError = false;
89
90  SmallVector<MCPendingError, 1> PendingErrors;
91  /// Flag tracking whether any errors have been encountered.
92
93public:
94  MCAsmParser(const MCAsmParser &) = delete;
95  MCAsmParser &operator=(const MCAsmParser &) = delete;
96  virtual ~MCAsmParser();
97
98  virtual void addDirectiveHandler(StringRef Directive,
99                                   ExtensionDirectiveHandler Handler) = 0;
100
101  virtual void addAliasForDirective(StringRef Directive, StringRef Alias) = 0;
102
103  virtual SourceMgr &getSourceManager() = 0;
104
105  virtual MCAsmLexer &getLexer() = 0;
106  const MCAsmLexer &getLexer() const {
107    return const_cast<MCAsmParser*>(this)->getLexer();
108  }
109
110  virtual MCContext &getContext() = 0;
111
112  /// \brief Return the output streamer for the assembler.
113  virtual MCStreamer &getStreamer() = 0;
114
115  MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
116  void setTargetParser(MCTargetAsmParser &P);
117
118  virtual unsigned getAssemblerDialect() { return 0;}
119  virtual void setAssemblerDialect(unsigned i) { }
120
121  bool getShowParsedOperands() const { return ShowParsedOperands; }
122  void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
123
124  /// \brief Run the parser on the input source buffer.
125  virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
126
127  virtual void setParsingInlineAsm(bool V) = 0;
128  virtual bool isParsingInlineAsm() = 0;
129
130  /// \brief Parse MS-style inline assembly.
131  virtual bool parseMSInlineAsm(
132      void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
133      unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
134      SmallVectorImpl<std::string> &Constraints,
135      SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
136      const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) = 0;
137
138  /// \brief Emit a note at the location \p L, with the message \p Msg.
139  virtual void Note(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
140
141  /// \brief Emit a warning at the location \p L, with the message \p Msg.
142  ///
143  /// \return The return value is true, if warnings are fatal.
144  virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
145
146  /// \brief Return an error at the location \p L, with the message \p Msg. This
147  /// may be modified before being emitted.
148  ///
149  /// \return The return value is always true, as an idiomatic convenience to
150  /// clients.
151  bool Error(SMLoc L, const Twine &Msg, SMRange Range = None);
152
153  /// \brief Emit an error at the location \p L, with the message \p Msg.
154  ///
155  /// \return The return value is always true, as an idiomatic convenience to
156  /// clients.
157  virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
158
159  bool hasPendingError() { return !PendingErrors.empty(); }
160
161  bool printPendingErrors() {
162    bool rv = !PendingErrors.empty();
163    for (auto Err : PendingErrors) {
164      printError(Err.Loc, Twine(Err.Msg), Err.Range);
165    }
166    PendingErrors.clear();
167    return rv;
168  }
169
170  bool addErrorSuffix(const Twine &Suffix);
171
172  /// \brief Get the next AsmToken in the stream, possibly handling file
173  /// inclusion first.
174  virtual const AsmToken &Lex() = 0;
175
176  /// \brief Get the current AsmToken from the stream.
177  const AsmToken &getTok() const;
178
179  /// \brief Report an error at the current lexer location.
180  bool TokError(const Twine &Msg, SMRange Range = None);
181
182  bool parseTokenLoc(SMLoc &Loc);
183  bool parseToken(AsmToken::TokenKind T, const Twine &Msg = "unexpected token");
184  /// \brief Attempt to parse and consume token, returning true on
185  /// success.
186  bool parseOptionalToken(AsmToken::TokenKind T);
187
188  bool parseEOL(const Twine &ErrMsg);
189
190  bool parseMany(function_ref<bool()> parseOne, bool hasComma = true);
191
192  bool parseIntToken(int64_t &V, const Twine &ErrMsg);
193
194  bool check(bool P, const Twine &Msg);
195  bool check(bool P, SMLoc Loc, const Twine &Msg);
196
197  /// \brief Parse an identifier or string (as a quoted identifier) and set \p
198  /// Res to the identifier contents.
199  virtual bool parseIdentifier(StringRef &Res) = 0;
200
201  /// \brief Parse up to the end of statement and return the contents from the
202  /// current token until the end of the statement; the current token on exit
203  /// will be either the EndOfStatement or EOF.
204  virtual StringRef parseStringToEndOfStatement() = 0;
205
206  /// \brief Parse the current token as a string which may include escaped
207  /// characters and return the string contents.
208  virtual bool parseEscapedString(std::string &Data) = 0;
209
210  /// \brief Skip to the end of the current statement, for error recovery.
211  virtual void eatToEndOfStatement() = 0;
212
213  /// \brief Parse an arbitrary expression.
214  ///
215  /// \param Res - The value of the expression. The result is undefined
216  /// on error.
217  /// \return - False on success.
218  virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
219  bool parseExpression(const MCExpr *&Res);
220
221  /// \brief Parse a primary expression.
222  ///
223  /// \param Res - The value of the expression. The result is undefined
224  /// on error.
225  /// \return - False on success.
226  virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0;
227
228  /// \brief Parse an arbitrary expression, assuming that an initial '(' has
229  /// already been consumed.
230  ///
231  /// \param Res - The value of the expression. The result is undefined
232  /// on error.
233  /// \return - False on success.
234  virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
235
236  /// \brief Parse an expression which must evaluate to an absolute value.
237  ///
238  /// \param Res - The value of the absolute expression. The result is undefined
239  /// on error.
240  /// \return - False on success.
241  virtual bool parseAbsoluteExpression(int64_t &Res) = 0;
242
243  /// \brief Ensure that we have a valid section set in the streamer. Otherwise,
244  /// report an error and switch to .text.
245  /// \return - False on success.
246  virtual bool checkForValidSection() = 0;
247
248  /// \brief Parse an arbitrary expression of a specified parenthesis depth,
249  /// assuming that the initial '(' characters have already been consumed.
250  ///
251  /// \param ParenDepth - Specifies how many trailing expressions outside the
252  /// current parentheses we have to parse.
253  /// \param Res - The value of the expression. The result is undefined
254  /// on error.
255  /// \return - False on success.
256  virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
257                                     SMLoc &EndLoc) = 0;
258};
259
260/// \brief Create an MCAsmParser instance.
261MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &,
262                               const MCAsmInfo &, unsigned CB = 0);
263
264} // end namespace llvm
265
266#endif // LLVM_MC_MCPARSER_MCASMPARSER_H
267