MCAsmParser.h 12 KB

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