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