MCAsmParser.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. //===-- MCAsmParser.cpp - Abstract Asm Parser Interface -------------------===//
  2. //
  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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/MC/MCParser/MCAsmParser.h"
  9. #include "llvm/ADT/StringRef.h"
  10. #include "llvm/ADT/Twine.h"
  11. #include "llvm/Config/llvm-config.h"
  12. #include "llvm/MC/MCParser/MCAsmLexer.h"
  13. #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
  14. #include "llvm/MC/MCParser/MCTargetAsmParser.h"
  15. #include "llvm/Support/CommandLine.h"
  16. #include "llvm/Support/Debug.h"
  17. #include "llvm/Support/SMLoc.h"
  18. #include "llvm/Support/raw_ostream.h"
  19. #include <cassert>
  20. using namespace llvm;
  21. namespace llvm {
  22. cl::opt<unsigned> AsmMacroMaxNestingDepth(
  23. "asm-macro-max-nesting-depth", cl::init(20), cl::Hidden,
  24. cl::desc("The maximum nesting depth allowed for assembly macros."));
  25. }
  26. MCAsmParser::MCAsmParser() = default;
  27. MCAsmParser::~MCAsmParser() = default;
  28. void MCAsmParser::setTargetParser(MCTargetAsmParser &P) {
  29. assert(!TargetParser && "Target parser is already initialized!");
  30. TargetParser = &P;
  31. TargetParser->Initialize(*this);
  32. }
  33. const AsmToken &MCAsmParser::getTok() const {
  34. return getLexer().getTok();
  35. }
  36. bool MCAsmParser::parseTokenLoc(SMLoc &Loc) {
  37. Loc = getTok().getLoc();
  38. return false;
  39. }
  40. bool MCAsmParser::parseEOL() {
  41. if (getTok().getKind() != AsmToken::EndOfStatement)
  42. return Error(getTok().getLoc(), "expected newline");
  43. Lex();
  44. return false;
  45. }
  46. bool MCAsmParser::parseEOL(const Twine &Msg) {
  47. if (getTok().getKind() != AsmToken::EndOfStatement)
  48. return Error(getTok().getLoc(), Msg);
  49. Lex();
  50. return false;
  51. }
  52. bool MCAsmParser::parseToken(AsmToken::TokenKind T, const Twine &Msg) {
  53. if (T == AsmToken::EndOfStatement)
  54. return parseEOL(Msg);
  55. if (getTok().getKind() != T)
  56. return Error(getTok().getLoc(), Msg);
  57. Lex();
  58. return false;
  59. }
  60. bool MCAsmParser::parseIntToken(int64_t &V, const Twine &Msg) {
  61. if (getTok().getKind() != AsmToken::Integer)
  62. return TokError(Msg);
  63. V = getTok().getIntVal();
  64. Lex();
  65. return false;
  66. }
  67. bool MCAsmParser::parseOptionalToken(AsmToken::TokenKind T) {
  68. bool Present = (getTok().getKind() == T);
  69. if (Present)
  70. parseToken(T);
  71. return Present;
  72. }
  73. bool MCAsmParser::check(bool P, const Twine &Msg) {
  74. return check(P, getTok().getLoc(), Msg);
  75. }
  76. bool MCAsmParser::check(bool P, SMLoc Loc, const Twine &Msg) {
  77. if (P)
  78. return Error(Loc, Msg);
  79. return false;
  80. }
  81. bool MCAsmParser::TokError(const Twine &Msg, SMRange Range) {
  82. return Error(getLexer().getLoc(), Msg, Range);
  83. }
  84. bool MCAsmParser::Error(SMLoc L, const Twine &Msg, SMRange Range) {
  85. MCPendingError PErr;
  86. PErr.Loc = L;
  87. Msg.toVector(PErr.Msg);
  88. PErr.Range = Range;
  89. PendingErrors.push_back(PErr);
  90. // If we threw this parsing error after a lexing error, this should
  91. // supercede the lexing error and so we remove it from the Lexer
  92. // before it can propagate
  93. if (getTok().is(AsmToken::Error))
  94. getLexer().Lex();
  95. return true;
  96. }
  97. bool MCAsmParser::addErrorSuffix(const Twine &Suffix) {
  98. // Make sure lexing errors have propagated to the parser.
  99. if (getTok().is(AsmToken::Error))
  100. Lex();
  101. for (auto &PErr : PendingErrors)
  102. Suffix.toVector(PErr.Msg);
  103. return true;
  104. }
  105. bool MCAsmParser::parseMany(function_ref<bool()> parseOne, bool hasComma) {
  106. if (parseOptionalToken(AsmToken::EndOfStatement))
  107. return false;
  108. while (true) {
  109. if (parseOne())
  110. return true;
  111. if (parseOptionalToken(AsmToken::EndOfStatement))
  112. return false;
  113. if (hasComma && parseToken(AsmToken::Comma))
  114. return true;
  115. }
  116. return false;
  117. }
  118. bool MCAsmParser::parseExpression(const MCExpr *&Res) {
  119. SMLoc L;
  120. return parseExpression(Res, L);
  121. }
  122. bool MCAsmParser::parseGNUAttribute(SMLoc L, int64_t &Tag,
  123. int64_t &IntegerValue) {
  124. // Parse a .gnu_attribute with numerical tag and value.
  125. StringRef S(L.getPointer());
  126. SMLoc TagLoc;
  127. TagLoc = getTok().getLoc();
  128. const AsmToken &Tok = getTok();
  129. if (Tok.isNot(AsmToken::Integer))
  130. return false;
  131. Tag = Tok.getIntVal();
  132. Lex(); // Eat the Tag
  133. Lex(); // Eat the comma
  134. if (Tok.isNot(AsmToken::Integer))
  135. return false;
  136. IntegerValue = Tok.getIntVal();
  137. Lex(); // Eat the IntegerValue
  138. return true;
  139. }
  140. void MCParsedAsmOperand::dump() const {
  141. // Cannot completely remove virtual function even in release mode.
  142. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  143. dbgs() << " " << *this;
  144. #endif
  145. }