1 //===-- MCAsmParser.cpp - Abstract Asm Parser Interface -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/MC/MCParser/MCAsmParser.h" 11 #include "llvm/ADT/StringRef.h" 12 #include "llvm/ADT/Twine.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() : ShowParsedOperands(0) {} 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 HadError = true; 89 90 MCPendingError PErr; 91 PErr.Loc = L; 92 Msg.toVector(PErr.Msg); 93 PErr.Range = Range; 94 PendingErrors.push_back(PErr); 95 96 // If we threw this parsing error after a lexing error, this should 97 // supercede the lexing error and so we remove it from the Lexer 98 // before it can propagate 99 if (getTok().is(AsmToken::Error)) 100 getLexer().Lex(); 101 return true; 102 } 103 104 bool MCAsmParser::addErrorSuffix(const Twine &Suffix) { 105 // Make sure lexing errors have propagated to the parser. 106 if (getTok().is(AsmToken::Error)) 107 Lex(); 108 for (auto &PErr : PendingErrors) 109 Suffix.toVector(PErr.Msg); 110 return true; 111 } 112 113 bool MCAsmParser::parseMany(function_ref<bool()> parseOne, bool hasComma) { 114 if (parseOptionalToken(AsmToken::EndOfStatement)) 115 return false; 116 while (true) { 117 if (parseOne()) 118 return true; 119 if (parseOptionalToken(AsmToken::EndOfStatement)) 120 return false; 121 if (hasComma && parseToken(AsmToken::Comma)) 122 return true; 123 } 124 return false; 125 } 126 127 bool MCAsmParser::parseExpression(const MCExpr *&Res) { 128 SMLoc L; 129 return parseExpression(Res, L); 130 } 131 132 void MCParsedAsmOperand::dump() const { 133 // Cannot completely remove virtual function even in release mode. 134 #ifdef LLVM_ENABLE_DUMP 135 dbgs() << " " << *this; 136 #endif 137 } 138