MCAsmParser.h 12 KB

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