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