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