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/Config/llvm-config.h" 14 #include "llvm/MC/MCParser/MCAsmLexer.h" 15 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 16 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 17 #include "llvm/Support/Debug.h" 18 #include "llvm/Support/SMLoc.h" 19 #include "llvm/Support/raw_ostream.h" 20 #include <cassert> 21 22 using namespace llvm; 23 24 MCAsmParser::MCAsmParser() {} 25 26 MCAsmParser::~MCAsmParser() = default; 27 28 void MCAsmParser::setTargetParser(MCTargetAsmParser &P) { 29 assert(!TargetParser && "Target parser is already initialized!"); 30 TargetParser = &P; 31 TargetParser->Initialize(*this); 32 } 33 34 const AsmToken &MCAsmParser::getTok() const { 35 return getLexer().getTok(); 36 } 37 38 bool MCAsmParser::parseTokenLoc(SMLoc &Loc) { 39 Loc = getTok().getLoc(); 40 return false; 41 } 42 43 bool MCAsmParser::parseEOL(const Twine &Msg) { 44 if (getTok().getKind() != AsmToken::EndOfStatement) 45 return Error(getTok().getLoc(), Msg); 46 Lex(); 47 return false; 48 } 49 50 bool MCAsmParser::parseToken(AsmToken::TokenKind T, const Twine &Msg) { 51 if (T == AsmToken::EndOfStatement) 52 return parseEOL(Msg); 53 if (getTok().getKind() != T) 54 return Error(getTok().getLoc(), Msg); 55 Lex(); 56 return false; 57 } 58 59 bool MCAsmParser::parseIntToken(int64_t &V, const Twine &Msg) { 60 if (getTok().getKind() != AsmToken::Integer) 61 return TokError(Msg); 62 V = getTok().getIntVal(); 63 Lex(); 64 return false; 65 } 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 74 bool MCAsmParser::check(bool P, const Twine &Msg) { 75 return check(P, getTok().getLoc(), Msg); 76 } 77 78 bool MCAsmParser::check(bool P, SMLoc Loc, const Twine &Msg) { 79 if (P) 80 return Error(Loc, Msg); 81 return false; 82 } 83 84 bool MCAsmParser::TokError(const Twine &Msg, SMRange Range) { 85 return Error(getLexer().getLoc(), Msg, Range); 86 } 87 88 bool MCAsmParser::Error(SMLoc L, const Twine &Msg, SMRange Range) { 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 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 135 dbgs() << " " << *this; 136 #endif 137 } 138