Line data Source code
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 :
25 : namespace llvm {
26 :
27 : class MCAsmInfo;
28 : class MCAsmParserExtension;
29 : class MCContext;
30 : class MCExpr;
31 : class MCInstPrinter;
32 : class MCInstrInfo;
33 : class MCStreamer;
34 : class MCTargetAsmParser;
35 : class SourceMgr;
36 :
37 : struct InlineAsmIdentifierInfo {
38 : enum IdKind {
39 : IK_Invalid, // Initial state. Unexpected after a successful parsing.
40 : IK_Label, // Function/Label reference.
41 : IK_EnumVal, // Value of enumeration type.
42 : IK_Var // Variable.
43 : };
44 : // Represents an Enum value
45 : struct EnumIdentifier {
46 : int64_t EnumVal;
47 : };
48 : // Represents a label/function reference
49 : struct LabelIdentifier {
50 : void *Decl;
51 : };
52 : // Represents a variable
53 : struct VariableIdentifier {
54 : void *Decl;
55 : bool IsGlobalLV;
56 : unsigned Length;
57 : unsigned Size;
58 : unsigned Type;
59 : };
60 : // An InlineAsm identifier can only be one of those
61 : union {
62 : EnumIdentifier Enum;
63 : LabelIdentifier Label;
64 : VariableIdentifier Var;
65 : };
66 0 : bool isKind(IdKind kind) const { return Kind == kind; }
67 : // Initializers
68 0 : void setEnum(int64_t enumVal) {
69 : assert(isKind(IK_Invalid) && "should be initialized only once");
70 17 : Kind = IK_EnumVal;
71 17 : Enum.EnumVal = enumVal;
72 0 : }
73 0 : void setLabel(void *decl) {
74 : assert(isKind(IK_Invalid) && "should be initialized only once");
75 13 : Kind = IK_Label;
76 13 : Label.Decl = decl;
77 0 : }
78 : void setVar(void *decl, bool isGlobalLV, unsigned size, unsigned type) {
79 : assert(isKind(IK_Invalid) && "should be initialized only once");
80 165 : Kind = IK_Var;
81 165 : Var.Decl = decl;
82 165 : Var.IsGlobalLV = isGlobalLV;
83 165 : Var.Size = size;
84 165 : Var.Type = type;
85 165 : Var.Length = size / type;
86 : }
87 9612 : InlineAsmIdentifierInfo() : Kind(IK_Invalid) {}
88 :
89 : private:
90 : // Discriminate using the current kind.
91 : IdKind Kind;
92 : };
93 :
94 : /// Generic Sema callback for assembly parser.
95 225 : class MCAsmParserSemaCallback {
96 : public:
97 : virtual ~MCAsmParserSemaCallback();
98 :
99 : virtual void LookupInlineAsmIdentifier(StringRef &LineBuf,
100 : InlineAsmIdentifierInfo &Info,
101 : bool IsUnevaluatedContext) = 0;
102 : virtual StringRef LookupInlineAsmLabel(StringRef Identifier, SourceMgr &SM,
103 : SMLoc Location, bool Create) = 0;
104 : virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
105 : unsigned &Offset) = 0;
106 : };
107 :
108 : /// Generic assembler parser interface, for use by target specific
109 : /// assembly parsers.
110 18513 : class MCAsmParser {
111 : public:
112 : using DirectiveHandler = bool (*)(MCAsmParserExtension*, StringRef, SMLoc);
113 : using ExtensionDirectiveHandler =
114 : std::pair<MCAsmParserExtension*, DirectiveHandler>;
115 :
116 134217 : struct MCPendingError {
117 : SMLoc Loc;
118 : SmallString<64> Msg;
119 : SMRange Range;
120 : };
121 :
122 : private:
123 : MCTargetAsmParser *TargetParser = nullptr;
124 :
125 : unsigned ShowParsedOperands : 1;
126 :
127 : protected: // Can only create subclasses.
128 : MCAsmParser();
129 :
130 : /// Flag tracking whether any errors have been encountered.
131 : bool HadError = false;
132 : /// Enable print [latency:throughput] in output file.
133 : bool EnablePrintSchedInfo = false;
134 :
135 : SmallVector<MCPendingError, 1> PendingErrors;
136 :
137 : public:
138 : MCAsmParser(const MCAsmParser &) = delete;
139 : MCAsmParser &operator=(const MCAsmParser &) = delete;
140 : virtual ~MCAsmParser();
141 :
142 : virtual void addDirectiveHandler(StringRef Directive,
143 : ExtensionDirectiveHandler Handler) = 0;
144 :
145 : virtual void addAliasForDirective(StringRef Directive, StringRef Alias) = 0;
146 :
147 : virtual SourceMgr &getSourceManager() = 0;
148 :
149 : virtual MCAsmLexer &getLexer() = 0;
150 : const MCAsmLexer &getLexer() const {
151 40004823 : return const_cast<MCAsmParser*>(this)->getLexer();
152 : }
153 :
154 : virtual MCContext &getContext() = 0;
155 :
156 : /// Return the output streamer for the assembler.
157 : virtual MCStreamer &getStreamer() = 0;
158 :
159 0 : MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
160 : void setTargetParser(MCTargetAsmParser &P);
161 :
162 0 : virtual unsigned getAssemblerDialect() { return 0;}
163 0 : virtual void setAssemblerDialect(unsigned i) { }
164 :
165 455867 : bool getShowParsedOperands() const { return ShowParsedOperands; }
166 7488 : void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
167 :
168 10296 : void setEnablePrintSchedInfo(bool Value) { EnablePrintSchedInfo = Value; }
169 0 : bool shouldPrintSchedInfo() { return EnablePrintSchedInfo; }
170 :
171 : /// Run the parser on the input source buffer.
172 : virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
173 :
174 : virtual void setParsingInlineAsm(bool V) = 0;
175 : virtual bool isParsingInlineAsm() = 0;
176 :
177 : /// Parse MS-style inline assembly.
178 : virtual bool parseMSInlineAsm(
179 : void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
180 : unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
181 : SmallVectorImpl<std::string> &Constraints,
182 : SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
183 : const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) = 0;
184 :
185 : /// Emit a note at the location \p L, with the message \p Msg.
186 : virtual void Note(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
187 :
188 : /// Emit a warning at the location \p L, with the message \p Msg.
189 : ///
190 : /// \return The return value is true, if warnings are fatal.
191 : virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
192 :
193 : /// Return an error at the location \p L, with the message \p Msg. This
194 : /// may be modified before being emitted.
195 : ///
196 : /// \return The return value is always true, as an idiomatic convenience to
197 : /// clients.
198 : bool Error(SMLoc L, const Twine &Msg, SMRange Range = None);
199 :
200 : /// Emit an error at the location \p L, with the message \p Msg.
201 : ///
202 : /// \return The return value is always true, as an idiomatic convenience to
203 : /// clients.
204 : virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
205 :
206 1961761 : bool hasPendingError() { return !PendingErrors.empty(); }
207 :
208 45741 : bool printPendingErrors() {
209 45741 : bool rv = !PendingErrors.empty();
210 90355 : for (auto Err : PendingErrors) {
211 89228 : printError(Err.Loc, Twine(Err.Msg), Err.Range);
212 : }
213 45741 : PendingErrors.clear();
214 45741 : return rv;
215 : }
216 :
217 3 : void clearPendingErrors() { PendingErrors.clear(); }
218 :
219 : bool addErrorSuffix(const Twine &Suffix);
220 :
221 : /// Get the next AsmToken in the stream, possibly handling file
222 : /// inclusion first.
223 : virtual const AsmToken &Lex() = 0;
224 :
225 : /// Get the current AsmToken from the stream.
226 : const AsmToken &getTok() const;
227 :
228 : /// Report an error at the current lexer location.
229 : bool TokError(const Twine &Msg, SMRange Range = None);
230 :
231 : bool parseTokenLoc(SMLoc &Loc);
232 : bool parseToken(AsmToken::TokenKind T, const Twine &Msg = "unexpected token");
233 : /// Attempt to parse and consume token, returning true on
234 : /// success.
235 : bool parseOptionalToken(AsmToken::TokenKind T);
236 :
237 : bool parseEOL(const Twine &ErrMsg);
238 :
239 : bool parseMany(function_ref<bool()> parseOne, bool hasComma = true);
240 :
241 : bool parseIntToken(int64_t &V, const Twine &ErrMsg);
242 :
243 : bool check(bool P, const Twine &Msg);
244 : bool check(bool P, SMLoc Loc, const Twine &Msg);
245 :
246 : /// Parse an identifier or string (as a quoted identifier) and set \p
247 : /// Res to the identifier contents.
248 : virtual bool parseIdentifier(StringRef &Res) = 0;
249 :
250 : /// Parse up to the end of statement and return the contents from the
251 : /// current token until the end of the statement; the current token on exit
252 : /// will be either the EndOfStatement or EOF.
253 : virtual StringRef parseStringToEndOfStatement() = 0;
254 :
255 : /// Parse the current token as a string which may include escaped
256 : /// characters and return the string contents.
257 : virtual bool parseEscapedString(std::string &Data) = 0;
258 :
259 : /// Skip to the end of the current statement, for error recovery.
260 : virtual void eatToEndOfStatement() = 0;
261 :
262 : /// Parse an arbitrary expression.
263 : ///
264 : /// \param Res - The value of the expression. The result is undefined
265 : /// on error.
266 : /// \return - False on success.
267 : virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
268 : bool parseExpression(const MCExpr *&Res);
269 :
270 : /// Parse a primary expression.
271 : ///
272 : /// \param Res - The value of the expression. The result is undefined
273 : /// on error.
274 : /// \return - False on success.
275 : virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0;
276 :
277 : /// Parse an arbitrary expression, assuming that an initial '(' has
278 : /// already been consumed.
279 : ///
280 : /// \param Res - The value of the expression. The result is undefined
281 : /// on error.
282 : /// \return - False on success.
283 : virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
284 :
285 : /// Parse an expression which must evaluate to an absolute value.
286 : ///
287 : /// \param Res - The value of the absolute expression. The result is undefined
288 : /// on error.
289 : /// \return - False on success.
290 : virtual bool parseAbsoluteExpression(int64_t &Res) = 0;
291 :
292 : /// Ensure that we have a valid section set in the streamer. Otherwise,
293 : /// report an error and switch to .text.
294 : /// \return - False on success.
295 : virtual bool checkForValidSection() = 0;
296 :
297 : /// Parse an arbitrary expression of a specified parenthesis depth,
298 : /// assuming that the initial '(' characters have already been consumed.
299 : ///
300 : /// \param ParenDepth - Specifies how many trailing expressions outside the
301 : /// current parentheses we have to parse.
302 : /// \param Res - The value of the expression. The result is undefined
303 : /// on error.
304 : /// \return - False on success.
305 : virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
306 : SMLoc &EndLoc) = 0;
307 : };
308 :
309 : /// Create an MCAsmParser instance.
310 : MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &,
311 : const MCAsmInfo &, unsigned CB = 0);
312 :
313 : } // end namespace llvm
314 :
315 : #endif // LLVM_MC_MCPARSER_MCASMPARSER_H
|