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 struct InlineAsmIdentifierInfo {
     38   enum IdKind {
     39     IK_Invalid,  // Initial state. Unexpected after a successful parsing.
     40     IK_Label,    // Function/Label reference.
     41     IK_EnumVal,  // Value of enumeration type.
     42     IK_Var       // Variable.
     43   };
     44   // Represents an Enum value
     45   struct EnumIdentifier {
     46     int64_t EnumVal;
     47   };
     48   // Represents a label/function reference
     49   struct LabelIdentifier {
     50     void *Decl;
     51   };
     52   // Represents a variable
     53   struct VariableIdentifier {
     54     void *Decl;
     55     bool IsGlobalLV;
     56     unsigned Length;
     57     unsigned Size;
     58     unsigned Type;
     59   };
     60   // An InlineAsm identifier can only be one of those
     61   union {
     62     EnumIdentifier Enum;
     63     LabelIdentifier Label;
     64     VariableIdentifier Var;
     65   };
     66   bool isKind(IdKind kind) const { return Kind == kind; }
     67   // Initializers
     68   void setEnum(int64_t enumVal) {
     69     assert(isKind(IK_Invalid) && "should be initialized only once");
     70     Kind = IK_EnumVal;
     71     Enum.EnumVal = enumVal;
     72   }
     73   void setLabel(void *decl) {
     74     assert(isKind(IK_Invalid) && "should be initialized only once");
     75     Kind = IK_Label;
     76     Label.Decl = decl;
     77   }
     78   void setVar(void *decl, bool isGlobalLV, unsigned size, unsigned type) {
     79     assert(isKind(IK_Invalid) && "should be initialized only once");
     80     Kind = IK_Var;
     81     Var.Decl = decl;
     82     Var.IsGlobalLV = isGlobalLV;
     83     Var.Size = size;
     84     Var.Type = type;
     85     Var.Length = size / type;
     86   }
     87   InlineAsmIdentifierInfo() : Kind(IK_Invalid) {}
     88 
     89 private:
     90   // Discriminate using the current kind.
     91   IdKind Kind;
     92 };
     93 
     94 /// \brief Generic Sema callback for assembly parser.
     95 class MCAsmParserSemaCallback {
     96 public:
     97   virtual ~MCAsmParserSemaCallback();
     98 
     99   virtual void LookupInlineAsmIdentifier(StringRef &LineBuf,
    100                                          InlineAsmIdentifierInfo &Info,
    101                                          bool IsUnevaluatedContext) = 0;
    102   virtual StringRef LookupInlineAsmLabel(StringRef Identifier, SourceMgr &SM,
    103                                          SMLoc Location, bool Create) = 0;
    104   virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
    105                                     unsigned &Offset) = 0;
    106 };
    107 
    108 /// \brief Generic assembler parser interface, for use by target specific
    109 /// assembly parsers.
    110 class MCAsmParser {
    111 public:
    112   using DirectiveHandler = bool (*)(MCAsmParserExtension*, StringRef, SMLoc);
    113   using ExtensionDirectiveHandler =
    114       std::pair<MCAsmParserExtension*, DirectiveHandler>;
    115 
    116   struct MCPendingError {
    117     SMLoc Loc;
    118     SmallString<64> Msg;
    119     SMRange Range;
    120   };
    121 
    122 private:
    123   MCTargetAsmParser *TargetParser = nullptr;
    124 
    125   unsigned ShowParsedOperands : 1;
    126 
    127 protected: // Can only create subclasses.
    128   MCAsmParser();
    129 
    130   bool HadError = false;
    131 
    132   SmallVector<MCPendingError, 1> PendingErrors;
    133   /// Flag tracking whether any errors have been encountered.
    134 
    135 public:
    136   MCAsmParser(const MCAsmParser &) = delete;
    137   MCAsmParser &operator=(const MCAsmParser &) = delete;
    138   virtual ~MCAsmParser();
    139 
    140   virtual void addDirectiveHandler(StringRef Directive,
    141                                    ExtensionDirectiveHandler Handler) = 0;
    142 
    143   virtual void addAliasForDirective(StringRef Directive, StringRef Alias) = 0;
    144 
    145   virtual SourceMgr &getSourceManager() = 0;
    146 
    147   virtual MCAsmLexer &getLexer() = 0;
    148   const MCAsmLexer &getLexer() const {
    149     return const_cast<MCAsmParser*>(this)->getLexer();
    150   }
    151 
    152   virtual MCContext &getContext() = 0;
    153 
    154   /// \brief Return the output streamer for the assembler.
    155   virtual MCStreamer &getStreamer() = 0;
    156 
    157   MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
    158   void setTargetParser(MCTargetAsmParser &P);
    159 
    160   virtual unsigned getAssemblerDialect() { return 0;}
    161   virtual void setAssemblerDialect(unsigned i) { }
    162 
    163   bool getShowParsedOperands() const { return ShowParsedOperands; }
    164   void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
    165 
    166   /// \brief Run the parser on the input source buffer.
    167   virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
    168 
    169   virtual void setParsingInlineAsm(bool V) = 0;
    170   virtual bool isParsingInlineAsm() = 0;
    171 
    172   /// \brief Parse MS-style inline assembly.
    173   virtual bool parseMSInlineAsm(
    174       void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
    175       unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
    176       SmallVectorImpl<std::string> &Constraints,
    177       SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
    178       const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) = 0;
    179 
    180   /// \brief Emit a note at the location \p L, with the message \p Msg.
    181   virtual void Note(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
    182 
    183   /// \brief Emit a warning at the location \p L, with the message \p Msg.
    184   ///
    185   /// \return The return value is true, if warnings are fatal.
    186   virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
    187 
    188   /// \brief Return an error at the location \p L, with the message \p Msg. This
    189   /// may be modified before being emitted.
    190   ///
    191   /// \return The return value is always true, as an idiomatic convenience to
    192   /// clients.
    193   bool Error(SMLoc L, const Twine &Msg, SMRange Range = None);
    194 
    195   /// \brief Emit an error at the location \p L, with the message \p Msg.
    196   ///
    197   /// \return The return value is always true, as an idiomatic convenience to
    198   /// clients.
    199   virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
    200 
    201   bool hasPendingError() { return !PendingErrors.empty(); }
    202 
    203   bool printPendingErrors() {
    204     bool rv = !PendingErrors.empty();
    205     for (auto Err : PendingErrors) {
    206       printError(Err.Loc, Twine(Err.Msg), Err.Range);
    207     }
    208     PendingErrors.clear();
    209     return rv;
    210   }
    211 
    212   bool addErrorSuffix(const Twine &Suffix);
    213 
    214   /// \brief Get the next AsmToken in the stream, possibly handling file
    215   /// inclusion first.
    216   virtual const AsmToken &Lex() = 0;
    217 
    218   /// \brief Get the current AsmToken from the stream.
    219   const AsmToken &getTok() const;
    220 
    221   /// \brief Report an error at the current lexer location.
    222   bool TokError(const Twine &Msg, SMRange Range = None);
    223 
    224   bool parseTokenLoc(SMLoc &Loc);
    225   bool parseToken(AsmToken::TokenKind T, const Twine &Msg = "unexpected token");
    226   /// \brief Attempt to parse and consume token, returning true on
    227   /// success.
    228   bool parseOptionalToken(AsmToken::TokenKind T);
    229 
    230   bool parseEOL(const Twine &ErrMsg);
    231 
    232   bool parseMany(function_ref<bool()> parseOne, bool hasComma = true);
    233 
    234   bool parseIntToken(int64_t &V, const Twine &ErrMsg);
    235 
    236   bool check(bool P, const Twine &Msg);
    237   bool check(bool P, SMLoc Loc, const Twine &Msg);
    238 
    239   /// \brief Parse an identifier or string (as a quoted identifier) and set \p
    240   /// Res to the identifier contents.
    241   virtual bool parseIdentifier(StringRef &Res) = 0;
    242 
    243   /// \brief Parse up to the end of statement and return the contents from the
    244   /// current token until the end of the statement; the current token on exit
    245   /// will be either the EndOfStatement or EOF.
    246   virtual StringRef parseStringToEndOfStatement() = 0;
    247 
    248   /// \brief Parse the current token as a string which may include escaped
    249   /// characters and return the string contents.
    250   virtual bool parseEscapedString(std::string &Data) = 0;
    251 
    252   /// \brief Skip to the end of the current statement, for error recovery.
    253   virtual void eatToEndOfStatement() = 0;
    254 
    255   /// \brief Parse an arbitrary expression.
    256   ///
    257   /// \param Res - The value of the expression. The result is undefined
    258   /// on error.
    259   /// \return - False on success.
    260   virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
    261   bool parseExpression(const MCExpr *&Res);
    262 
    263   /// \brief Parse a primary expression.
    264   ///
    265   /// \param Res - The value of the expression. The result is undefined
    266   /// on error.
    267   /// \return - False on success.
    268   virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0;
    269 
    270   /// \brief Parse an arbitrary expression, assuming that an initial '(' has
    271   /// already been consumed.
    272   ///
    273   /// \param Res - The value of the expression. The result is undefined
    274   /// on error.
    275   /// \return - False on success.
    276   virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
    277 
    278   /// \brief Parse an expression which must evaluate to an absolute value.
    279   ///
    280   /// \param Res - The value of the absolute expression. The result is undefined
    281   /// on error.
    282   /// \return - False on success.
    283   virtual bool parseAbsoluteExpression(int64_t &Res) = 0;
    284 
    285   /// \brief Ensure that we have a valid section set in the streamer. Otherwise,
    286   /// report an error and switch to .text.
    287   /// \return - False on success.
    288   virtual bool checkForValidSection() = 0;
    289 
    290   /// \brief Parse an arbitrary expression of a specified parenthesis depth,
    291   /// assuming that the initial '(' characters have already been consumed.
    292   ///
    293   /// \param ParenDepth - Specifies how many trailing expressions outside the
    294   /// current parentheses we have to parse.
    295   /// \param Res - The value of the expression. The result is undefined
    296   /// on error.
    297   /// \return - False on success.
    298   virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
    299                                      SMLoc &EndLoc) = 0;
    300 };
    301 
    302 /// \brief Create an MCAsmParser instance.
    303 MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &,
    304                                const MCAsmInfo &, unsigned CB = 0);
    305 
    306 } // end namespace llvm
    307 
    308 #endif // LLVM_MC_MCPARSER_MCASMPARSER_H
    309