Home | History | Annotate | Download | only in MCParser
      1 //===- llvm/MC/MCAsmParser.h - Abstract Asm Parser Interface ----*- C++ -*-===//
      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 #ifndef LLVM_MC_MCPARSER_MCASMPARSER_H
     11 #define LLVM_MC_MCPARSER_MCASMPARSER_H
     12 
     13 #include "llvm/ADT/None.h"
     14 #include "llvm/ADT/STLExtras.h"
     15 #include "llvm/ADT/SmallString.h"
     16 #include "llvm/ADT/SmallVector.h"
     17 #include "llvm/ADT/StringRef.h"
     18 #include "llvm/ADT/Twine.h"
     19 #include "llvm/MC/MCParser/MCAsmLexer.h"
     20 #include "llvm/Support/SMLoc.h"
     21 #include <cstdint>
     22 #include <string>
     23 #include <utility>
     24 
     25 namespace llvm {
     26 
     27 class MCAsmInfo;
     28 class MCAsmParserExtension;
     29 class MCContext;
     30 class MCExpr;
     31 class MCInstPrinter;
     32 class MCInstrInfo;
     33 class MCStreamer;
     34 class MCTargetAsmParser;
     35 class SourceMgr;
     36 
     37 class InlineAsmIdentifierInfo {
     38 public:
     39   void *OpDecl;
     40   bool IsVarDecl;
     41   unsigned Length, Size, Type;
     42 
     43   void clear() {
     44     OpDecl = nullptr;
     45     IsVarDecl = false;
     46     Length = 1;
     47     Size = 0;
     48     Type = 0;
     49   }
     50 };
     51 
     52 /// \brief Generic Sema callback for assembly parser.
     53 class MCAsmParserSemaCallback {
     54 public:
     55   virtual ~MCAsmParserSemaCallback();
     56 
     57   virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf,
     58                                           InlineAsmIdentifierInfo &Info,
     59                                           bool IsUnevaluatedContext) = 0;
     60   virtual StringRef LookupInlineAsmLabel(StringRef Identifier, SourceMgr &SM,
     61                                          SMLoc Location, bool Create) = 0;
     62   virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
     63                                     unsigned &Offset) = 0;
     64 };
     65 
     66 /// \brief Generic assembler parser interface, for use by target specific
     67 /// assembly parsers.
     68 class MCAsmParser {
     69 public:
     70   using DirectiveHandler = bool (*)(MCAsmParserExtension*, StringRef, SMLoc);
     71   using ExtensionDirectiveHandler =
     72       std::pair<MCAsmParserExtension*, DirectiveHandler>;
     73 
     74   struct MCPendingError {
     75     SMLoc Loc;
     76     SmallString<64> Msg;
     77     SMRange Range;
     78   };
     79 
     80 private:
     81   MCTargetAsmParser *TargetParser = nullptr;
     82 
     83   unsigned ShowParsedOperands : 1;
     84 
     85 protected: // Can only create subclasses.
     86   MCAsmParser();
     87 
     88   bool HadError = false;
     89 
     90   SmallVector<MCPendingError, 1> PendingErrors;
     91   /// Flag tracking whether any errors have been encountered.
     92 
     93 public:
     94   MCAsmParser(const MCAsmParser &) = delete;
     95   MCAsmParser &operator=(const MCAsmParser &) = delete;
     96   virtual ~MCAsmParser();
     97 
     98   virtual void addDirectiveHandler(StringRef Directive,
     99                                    ExtensionDirectiveHandler Handler) = 0;
    100 
    101   virtual void addAliasForDirective(StringRef Directive, StringRef Alias) = 0;
    102 
    103   virtual SourceMgr &getSourceManager() = 0;
    104 
    105   virtual MCAsmLexer &getLexer() = 0;
    106   const MCAsmLexer &getLexer() const {
    107     return const_cast<MCAsmParser*>(this)->getLexer();
    108   }
    109 
    110   virtual MCContext &getContext() = 0;
    111 
    112   /// \brief Return the output streamer for the assembler.
    113   virtual MCStreamer &getStreamer() = 0;
    114 
    115   MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
    116   void setTargetParser(MCTargetAsmParser &P);
    117 
    118   virtual unsigned getAssemblerDialect() { return 0;}
    119   virtual void setAssemblerDialect(unsigned i) { }
    120 
    121   bool getShowParsedOperands() const { return ShowParsedOperands; }
    122   void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
    123 
    124   /// \brief Run the parser on the input source buffer.
    125   virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
    126 
    127   virtual void setParsingInlineAsm(bool V) = 0;
    128   virtual bool isParsingInlineAsm() = 0;
    129 
    130   /// \brief Parse MS-style inline assembly.
    131   virtual bool parseMSInlineAsm(
    132       void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
    133       unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
    134       SmallVectorImpl<std::string> &Constraints,
    135       SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
    136       const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) = 0;
    137 
    138   /// \brief Emit a note at the location \p L, with the message \p Msg.
    139   virtual void Note(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
    140 
    141   /// \brief Emit a warning at the location \p L, with the message \p Msg.
    142   ///
    143   /// \return The return value is true, if warnings are fatal.
    144   virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
    145 
    146   /// \brief Return an error at the location \p L, with the message \p Msg. This
    147   /// may be modified before being emitted.
    148   ///
    149   /// \return The return value is always true, as an idiomatic convenience to
    150   /// clients.
    151   bool Error(SMLoc L, const Twine &Msg, SMRange Range = None);
    152 
    153   /// \brief Emit an error at the location \p L, with the message \p Msg.
    154   ///
    155   /// \return The return value is always true, as an idiomatic convenience to
    156   /// clients.
    157   virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
    158 
    159   bool hasPendingError() { return !PendingErrors.empty(); }
    160 
    161   bool printPendingErrors() {
    162     bool rv = !PendingErrors.empty();
    163     for (auto Err : PendingErrors) {
    164       printError(Err.Loc, Twine(Err.Msg), Err.Range);
    165     }
    166     PendingErrors.clear();
    167     return rv;
    168   }
    169 
    170   bool addErrorSuffix(const Twine &Suffix);
    171 
    172   /// \brief Get the next AsmToken in the stream, possibly handling file
    173   /// inclusion first.
    174   virtual const AsmToken &Lex() = 0;
    175 
    176   /// \brief Get the current AsmToken from the stream.
    177   const AsmToken &getTok() const;
    178 
    179   /// \brief Report an error at the current lexer location.
    180   bool TokError(const Twine &Msg, SMRange Range = None);
    181 
    182   bool parseTokenLoc(SMLoc &Loc);
    183   bool parseToken(AsmToken::TokenKind T, const Twine &Msg = "unexpected token");
    184   /// \brief Attempt to parse and consume token, returning true on
    185   /// success.
    186   bool parseOptionalToken(AsmToken::TokenKind T);
    187 
    188   bool parseEOL(const Twine &ErrMsg);
    189 
    190   bool parseMany(function_ref<bool()> parseOne, bool hasComma = true);
    191 
    192   bool parseIntToken(int64_t &V, const Twine &ErrMsg);
    193 
    194   bool check(bool P, const Twine &Msg);
    195   bool check(bool P, SMLoc Loc, const Twine &Msg);
    196 
    197   /// \brief Parse an identifier or string (as a quoted identifier) and set \p
    198   /// Res to the identifier contents.
    199   virtual bool parseIdentifier(StringRef &Res) = 0;
    200 
    201   /// \brief Parse up to the end of statement and return the contents from the
    202   /// current token until the end of the statement; the current token on exit
    203   /// will be either the EndOfStatement or EOF.
    204   virtual StringRef parseStringToEndOfStatement() = 0;
    205 
    206   /// \brief Parse the current token as a string which may include escaped
    207   /// characters and return the string contents.
    208   virtual bool parseEscapedString(std::string &Data) = 0;
    209 
    210   /// \brief Skip to the end of the current statement, for error recovery.
    211   virtual void eatToEndOfStatement() = 0;
    212 
    213   /// \brief Parse an arbitrary expression.
    214   ///
    215   /// \param Res - The value of the expression. The result is undefined
    216   /// on error.
    217   /// \return - False on success.
    218   virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
    219   bool parseExpression(const MCExpr *&Res);
    220 
    221   /// \brief Parse a primary expression.
    222   ///
    223   /// \param Res - The value of the expression. The result is undefined
    224   /// on error.
    225   /// \return - False on success.
    226   virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0;
    227 
    228   /// \brief Parse an arbitrary expression, assuming that an initial '(' has
    229   /// already been consumed.
    230   ///
    231   /// \param Res - The value of the expression. The result is undefined
    232   /// on error.
    233   /// \return - False on success.
    234   virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
    235 
    236   /// \brief Parse an expression which must evaluate to an absolute value.
    237   ///
    238   /// \param Res - The value of the absolute expression. The result is undefined
    239   /// on error.
    240   /// \return - False on success.
    241   virtual bool parseAbsoluteExpression(int64_t &Res) = 0;
    242 
    243   /// \brief Ensure that we have a valid section set in the streamer. Otherwise,
    244   /// report an error and switch to .text.
    245   /// \return - False on success.
    246   virtual bool checkForValidSection() = 0;
    247 
    248   /// \brief Parse an arbitrary expression of a specified parenthesis depth,
    249   /// assuming that the initial '(' characters have already been consumed.
    250   ///
    251   /// \param ParenDepth - Specifies how many trailing expressions outside the
    252   /// current parentheses we have to parse.
    253   /// \param Res - The value of the expression. The result is undefined
    254   /// on error.
    255   /// \return - False on success.
    256   virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
    257                                      SMLoc &EndLoc) = 0;
    258 };
    259 
    260 /// \brief Create an MCAsmParser instance.
    261 MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &,
    262                                const MCAsmInfo &, unsigned CB = 0);
    263 
    264 } // end namespace llvm
    265 
    266 #endif // LLVM_MC_MCPARSER_MCASMPARSER_H
    267