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 21using namespace llvm; 22 23MCAsmParser::MCAsmParser() {} 24 25MCAsmParser::~MCAsmParser() = default; 26 27void MCAsmParser::setTargetParser(MCTargetAsmParser &P) { 28 assert(!TargetParser && "Target parser is already initialized!"); 29 TargetParser = &P; 30 TargetParser->Initialize(*this); 31} 32 33const AsmToken &MCAsmParser::getTok() const { 34 return getLexer().getTok(); 35} 36 37bool MCAsmParser::parseTokenLoc(SMLoc &Loc) { 38 Loc = getTok().getLoc(); 39 return false; 40} 41 42bool MCAsmParser::parseEOL(const Twine &Msg) { 43 if (getTok().getKind() != AsmToken::EndOfStatement) 44 return Error(getTok().getLoc(), Msg); 45 Lex(); 46 return false; 47} 48 49bool 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 58bool 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 66bool MCAsmParser::parseOptionalToken(AsmToken::TokenKind T) { 67 bool Present = (getTok().getKind() == T); 68 if (Present) 69 parseToken(T); 70 return Present; 71} 72 73bool MCAsmParser::check(bool P, const Twine &Msg) { 74 return check(P, getTok().getLoc(), Msg); 75} 76 77bool MCAsmParser::check(bool P, SMLoc Loc, const Twine &Msg) { 78 if (P) 79 return Error(Loc, Msg); 80 return false; 81} 82 83bool MCAsmParser::TokError(const Twine &Msg, SMRange Range) { 84 return Error(getLexer().getLoc(), Msg, Range); 85} 86 87bool 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 103bool 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 112bool 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 126bool MCAsmParser::parseExpression(const MCExpr *&Res) { 127 SMLoc L; 128 return parseExpression(Res, L); 129} 130 131void 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