1 //===- llvm/MC/MCAsmParser.h - Abstract Asm Parser Interface ----*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_MC_MCPARSER_MCASMPARSER_H
10 #define LLVM_MC_MCPARSER_MCASMPARSER_H
12 #include "llvm/ADT/None.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/SmallString.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/MC/MCParser/MCAsmLexer.h"
19 #include "llvm/Support/SMLoc.h"
27 class MCAsmParserExtension
;
33 class MCTargetAsmParser
;
36 struct InlineAsmIdentifierInfo
{
38 IK_Invalid
, // Initial state. Unexpected after a successful parsing.
39 IK_Label
, // Function/Label reference.
40 IK_EnumVal
, // Value of enumeration type.
43 // Represents an Enum value
44 struct EnumIdentifier
{
47 // Represents a label/function reference
48 struct LabelIdentifier
{
51 // Represents a variable
52 struct VariableIdentifier
{
59 // An InlineAsm identifier can only be one of those
62 LabelIdentifier Label
;
63 VariableIdentifier Var
;
65 bool isKind(IdKind kind
) const { return Kind
== kind
; }
67 void setEnum(int64_t enumVal
) {
68 assert(isKind(IK_Invalid
) && "should be initialized only once");
70 Enum
.EnumVal
= enumVal
;
72 void setLabel(void *decl
) {
73 assert(isKind(IK_Invalid
) && "should be initialized only once");
77 void setVar(void *decl
, bool isGlobalLV
, unsigned size
, unsigned type
) {
78 assert(isKind(IK_Invalid
) && "should be initialized only once");
81 Var
.IsGlobalLV
= isGlobalLV
;
84 Var
.Length
= size
/ type
;
86 InlineAsmIdentifierInfo() : Kind(IK_Invalid
) {}
89 // Discriminate using the current kind.
93 /// Generic Sema callback for assembly parser.
94 class MCAsmParserSemaCallback
{
96 virtual ~MCAsmParserSemaCallback();
98 virtual void LookupInlineAsmIdentifier(StringRef
&LineBuf
,
99 InlineAsmIdentifierInfo
&Info
,
100 bool IsUnevaluatedContext
) = 0;
101 virtual StringRef
LookupInlineAsmLabel(StringRef Identifier
, SourceMgr
&SM
,
102 SMLoc Location
, bool Create
) = 0;
103 virtual bool LookupInlineAsmField(StringRef Base
, StringRef Member
,
104 unsigned &Offset
) = 0;
107 /// Generic assembler parser interface, for use by target specific
108 /// assembly parsers.
111 using DirectiveHandler
= bool (*)(MCAsmParserExtension
*, StringRef
, SMLoc
);
112 using ExtensionDirectiveHandler
=
113 std::pair
<MCAsmParserExtension
*, DirectiveHandler
>;
115 struct MCPendingError
{
122 MCTargetAsmParser
*TargetParser
= nullptr;
124 protected: // Can only create subclasses.
127 SmallVector
<MCPendingError
, 0> PendingErrors
;
129 /// Flag tracking whether any errors have been encountered.
130 bool HadError
= false;
132 bool ShowParsedOperands
= false;
135 MCAsmParser(const MCAsmParser
&) = delete;
136 MCAsmParser
&operator=(const MCAsmParser
&) = delete;
137 virtual ~MCAsmParser();
139 virtual void addDirectiveHandler(StringRef Directive
,
140 ExtensionDirectiveHandler Handler
) = 0;
142 virtual void addAliasForDirective(StringRef Directive
, StringRef Alias
) = 0;
144 virtual SourceMgr
&getSourceManager() = 0;
146 virtual MCAsmLexer
&getLexer() = 0;
147 const MCAsmLexer
&getLexer() const {
148 return const_cast<MCAsmParser
*>(this)->getLexer();
151 virtual MCContext
&getContext() = 0;
153 /// Return the output streamer for the assembler.
154 virtual MCStreamer
&getStreamer() = 0;
156 MCTargetAsmParser
&getTargetParser() const { return *TargetParser
; }
157 void setTargetParser(MCTargetAsmParser
&P
);
159 virtual unsigned getAssemblerDialect() { return 0;}
160 virtual void setAssemblerDialect(unsigned i
) { }
162 bool getShowParsedOperands() const { return ShowParsedOperands
; }
163 void setShowParsedOperands(bool Value
) { ShowParsedOperands
= Value
; }
165 /// Run the parser on the input source buffer.
166 virtual bool Run(bool NoInitialTextSection
, bool NoFinalize
= false) = 0;
168 virtual void setParsingInlineAsm(bool V
) = 0;
169 virtual bool isParsingInlineAsm() = 0;
171 /// Parse MS-style inline assembly.
172 virtual bool parseMSInlineAsm(
173 void *AsmLoc
, std::string
&AsmString
, unsigned &NumOutputs
,
174 unsigned &NumInputs
, SmallVectorImpl
<std::pair
<void *, bool>> &OpDecls
,
175 SmallVectorImpl
<std::string
> &Constraints
,
176 SmallVectorImpl
<std::string
> &Clobbers
, const MCInstrInfo
*MII
,
177 const MCInstPrinter
*IP
, MCAsmParserSemaCallback
&SI
) = 0;
179 /// Emit a note at the location \p L, with the message \p Msg.
180 virtual void Note(SMLoc L
, const Twine
&Msg
, SMRange Range
= None
) = 0;
182 /// Emit a warning at the location \p L, with the message \p Msg.
184 /// \return The return value is true, if warnings are fatal.
185 virtual bool Warning(SMLoc L
, const Twine
&Msg
, SMRange Range
= None
) = 0;
187 /// Return an error at the location \p L, with the message \p Msg. This
188 /// may be modified before being emitted.
190 /// \return The return value is always true, as an idiomatic convenience to
192 bool Error(SMLoc L
, const Twine
&Msg
, SMRange Range
= None
);
194 /// Emit an error at the location \p L, with the message \p Msg.
196 /// \return The return value is always true, as an idiomatic convenience to
198 virtual bool printError(SMLoc L
, const Twine
&Msg
, SMRange Range
= None
) = 0;
200 bool hasPendingError() { return !PendingErrors
.empty(); }
202 bool printPendingErrors() {
203 bool rv
= !PendingErrors
.empty();
204 for (auto Err
: PendingErrors
) {
205 printError(Err
.Loc
, Twine(Err
.Msg
), Err
.Range
);
207 PendingErrors
.clear();
211 void clearPendingErrors() { PendingErrors
.clear(); }
213 bool addErrorSuffix(const Twine
&Suffix
);
215 /// Get the next AsmToken in the stream, possibly handling file
217 virtual const AsmToken
&Lex() = 0;
219 /// Get the current AsmToken from the stream.
220 const AsmToken
&getTok() const;
222 /// Report an error at the current lexer location.
223 bool TokError(const Twine
&Msg
, SMRange Range
= None
);
225 bool parseTokenLoc(SMLoc
&Loc
);
226 bool parseToken(AsmToken::TokenKind T
, const Twine
&Msg
= "unexpected token");
227 /// Attempt to parse and consume token, returning true on
229 bool parseOptionalToken(AsmToken::TokenKind T
);
231 bool parseEOL(const Twine
&ErrMsg
);
233 bool parseMany(function_ref
<bool()> parseOne
, bool hasComma
= true);
235 bool parseIntToken(int64_t &V
, const Twine
&ErrMsg
);
237 bool check(bool P
, const Twine
&Msg
);
238 bool check(bool P
, SMLoc Loc
, const Twine
&Msg
);
240 /// Parse an identifier or string (as a quoted identifier) and set \p
241 /// Res to the identifier contents.
242 virtual bool parseIdentifier(StringRef
&Res
) = 0;
244 /// Parse up to the end of statement and return the contents from the
245 /// current token until the end of the statement; the current token on exit
246 /// will be either the EndOfStatement or EOF.
247 virtual StringRef
parseStringToEndOfStatement() = 0;
249 /// Parse the current token as a string which may include escaped
250 /// characters and return the string contents.
251 virtual bool parseEscapedString(std::string
&Data
) = 0;
253 /// Skip to the end of the current statement, for error recovery.
254 virtual void eatToEndOfStatement() = 0;
256 /// Parse an arbitrary expression.
258 /// \param Res - The value of the expression. The result is undefined
260 /// \return - False on success.
261 virtual bool parseExpression(const MCExpr
*&Res
, SMLoc
&EndLoc
) = 0;
262 bool parseExpression(const MCExpr
*&Res
);
264 /// Parse a primary expression.
266 /// \param Res - The value of the expression. The result is undefined
268 /// \return - False on success.
269 virtual bool parsePrimaryExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
) = 0;
271 /// Parse an arbitrary expression, assuming that an initial '(' has
272 /// already been consumed.
274 /// \param Res - The value of the expression. The result is undefined
276 /// \return - False on success.
277 virtual bool parseParenExpression(const MCExpr
*&Res
, SMLoc
&EndLoc
) = 0;
279 /// Parse an expression which must evaluate to an absolute value.
281 /// \param Res - The value of the absolute expression. The result is undefined
283 /// \return - False on success.
284 virtual bool parseAbsoluteExpression(int64_t &Res
) = 0;
286 /// Ensure that we have a valid section set in the streamer. Otherwise,
287 /// report an error and switch to .text.
288 /// \return - False on success.
289 virtual bool checkForValidSection() = 0;
291 /// Parse an arbitrary expression of a specified parenthesis depth,
292 /// assuming that the initial '(' characters have already been consumed.
294 /// \param ParenDepth - Specifies how many trailing expressions outside the
295 /// current parentheses we have to parse.
296 /// \param Res - The value of the expression. The result is undefined
298 /// \return - False on success.
299 virtual bool parseParenExprOfDepth(unsigned ParenDepth
, const MCExpr
*&Res
,
303 /// Create an MCAsmParser instance.
304 MCAsmParser
*createMCAsmParser(SourceMgr
&, MCContext
&, MCStreamer
&,
305 const MCAsmInfo
&, unsigned CB
= 0);
307 } // end namespace llvm
309 #endif // LLVM_MC_MCPARSER_MCASMPARSER_H