• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer 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_MCASMLEXER_H
11 #define LLVM_MC_MCPARSER_MCASMLEXER_H
12 
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/MC/MCAsmMacro.h"
16 #include <algorithm>
17 #include <cassert>
18 #include <cstddef>
19 #include <cstdint>
20 #include <string>
21 
22 namespace llvm {
23 
24 /// A callback class which is notified of each comment in an assembly file as
25 /// it is lexed.
26 class AsmCommentConsumer {
27 public:
28   virtual ~AsmCommentConsumer() = default;
29 
30   /// Callback function for when a comment is lexed. Loc is the start of the
31   /// comment text (excluding the comment-start marker). CommentText is the text
32   /// of the comment, excluding the comment start and end markers, and the
33   /// newline for single-line comments.
34   virtual void HandleComment(SMLoc Loc, StringRef CommentText) = 0;
35 };
36 
37 
38 /// Generic assembler lexer interface, for use by target specific assembly
39 /// lexers.
40 class MCAsmLexer {
41   /// The current token, stored in the base class for faster access.
42   SmallVector<AsmToken, 1> CurTok;
43 
44   /// The location and description of the current error
45   SMLoc ErrLoc;
46   std::string Err;
47 
48 protected: // Can only create subclasses.
49   const char *TokStart = nullptr;
50   bool SkipSpace = true;
51   bool AllowAtInIdentifier;
52   bool IsAtStartOfStatement = true;
53   AsmCommentConsumer *CommentConsumer = nullptr;
54 
55   bool AltMacroMode;
56   MCAsmLexer();
57 
58   virtual AsmToken LexToken() = 0;
59 
SetError(SMLoc errLoc,const std::string & err)60   void SetError(SMLoc errLoc, const std::string &err) {
61     ErrLoc = errLoc;
62     Err = err;
63   }
64 
65 public:
66   MCAsmLexer(const MCAsmLexer &) = delete;
67   MCAsmLexer &operator=(const MCAsmLexer &) = delete;
68   virtual ~MCAsmLexer();
69 
IsaAltMacroMode()70   bool IsaAltMacroMode() {
71     return AltMacroMode;
72   }
73 
SetAltMacroMode(bool AltMacroSet)74   void SetAltMacroMode(bool AltMacroSet) {
75     AltMacroMode = AltMacroSet;
76   }
77 
78   /// Consume the next token from the input stream and return it.
79   ///
80   /// The lexer will continuosly return the end-of-file token once the end of
81   /// the main input file has been reached.
Lex()82   const AsmToken &Lex() {
83     assert(!CurTok.empty());
84     // Mark if we parsing out a EndOfStatement.
85     IsAtStartOfStatement = CurTok.front().getKind() == AsmToken::EndOfStatement;
86     CurTok.erase(CurTok.begin());
87     // LexToken may generate multiple tokens via UnLex but will always return
88     // the first one. Place returned value at head of CurTok vector.
89     if (CurTok.empty()) {
90       AsmToken T = LexToken();
91       CurTok.insert(CurTok.begin(), T);
92     }
93     return CurTok.front();
94   }
95 
UnLex(AsmToken const & Token)96   void UnLex(AsmToken const &Token) {
97     IsAtStartOfStatement = false;
98     CurTok.insert(CurTok.begin(), Token);
99   }
100 
isAtStartOfStatement()101   bool isAtStartOfStatement() { return IsAtStartOfStatement; }
102 
103   virtual StringRef LexUntilEndOfStatement() = 0;
104 
105   /// Get the current source location.
106   SMLoc getLoc() const;
107 
108   /// Get the current (last) lexed token.
getTok()109   const AsmToken &getTok() const {
110     return CurTok[0];
111   }
112 
113   /// Look ahead at the next token to be lexed.
114   const AsmToken peekTok(bool ShouldSkipSpace = true) {
115     AsmToken Tok;
116 
117     MutableArrayRef<AsmToken> Buf(Tok);
118     size_t ReadCount = peekTokens(Buf, ShouldSkipSpace);
119 
120     assert(ReadCount == 1);
121     (void)ReadCount;
122 
123     return Tok;
124   }
125 
126   /// Look ahead an arbitrary number of tokens.
127   virtual size_t peekTokens(MutableArrayRef<AsmToken> Buf,
128                             bool ShouldSkipSpace = true) = 0;
129 
130   /// Get the current error location
getErrLoc()131   SMLoc getErrLoc() {
132     return ErrLoc;
133   }
134 
135   /// Get the current error string
getErr()136   const std::string &getErr() {
137     return Err;
138   }
139 
140   /// Get the kind of current token.
getKind()141   AsmToken::TokenKind getKind() const { return getTok().getKind(); }
142 
143   /// Check if the current token has kind \p K.
is(AsmToken::TokenKind K)144   bool is(AsmToken::TokenKind K) const { return getTok().is(K); }
145 
146   /// Check if the current token has kind \p K.
isNot(AsmToken::TokenKind K)147   bool isNot(AsmToken::TokenKind K) const { return getTok().isNot(K); }
148 
149   /// Set whether spaces should be ignored by the lexer
setSkipSpace(bool val)150   void setSkipSpace(bool val) { SkipSpace = val; }
151 
getAllowAtInIdentifier()152   bool getAllowAtInIdentifier() { return AllowAtInIdentifier; }
setAllowAtInIdentifier(bool v)153   void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; }
154 
setCommentConsumer(AsmCommentConsumer * CommentConsumer)155   void setCommentConsumer(AsmCommentConsumer *CommentConsumer) {
156     this->CommentConsumer = CommentConsumer;
157   }
158 };
159 
160 } // end namespace llvm
161 
162 #endif // LLVM_MC_MCPARSER_MCASMLEXER_H
163