Line data Source code
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 0 : 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 18582 : 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 : MCAsmLexer();
56 :
57 : virtual AsmToken LexToken() = 0;
58 :
59 : void SetError(SMLoc errLoc, const std::string &err) {
60 510512 : ErrLoc = errLoc;
61 510512 : Err = err;
62 : }
63 :
64 : public:
65 : MCAsmLexer(const MCAsmLexer &) = delete;
66 : MCAsmLexer &operator=(const MCAsmLexer &) = delete;
67 : virtual ~MCAsmLexer();
68 :
69 : /// Consume the next token from the input stream and return it.
70 : ///
71 : /// The lexer will continuously return the end-of-file token once the end of
72 : /// the main input file has been reached.
73 8998403 : const AsmToken &Lex() {
74 : assert(!CurTok.empty());
75 : // Mark if we parsing out a EndOfStatement.
76 8998403 : IsAtStartOfStatement = CurTok.front().getKind() == AsmToken::EndOfStatement;
77 8998403 : CurTok.erase(CurTok.begin());
78 : // LexToken may generate multiple tokens via UnLex but will always return
79 : // the first one. Place returned value at head of CurTok vector.
80 8998403 : if (CurTok.empty()) {
81 8979812 : AsmToken T = LexToken();
82 8979812 : CurTok.insert(CurTok.begin(), T);
83 : }
84 8998403 : return CurTok.front();
85 : }
86 :
87 : void UnLex(AsmToken const &Token) {
88 18561 : IsAtStartOfStatement = false;
89 37122 : CurTok.insert(CurTok.begin(), Token);
90 : }
91 :
92 0 : bool isAtStartOfStatement() { return IsAtStartOfStatement; }
93 :
94 : virtual StringRef LexUntilEndOfStatement() = 0;
95 :
96 : /// Get the current source location.
97 : SMLoc getLoc() const;
98 :
99 : /// Get the current (last) lexed token.
100 : const AsmToken &getTok() const {
101 : return CurTok[0];
102 : }
103 :
104 : /// Look ahead at the next token to be lexed.
105 : const AsmToken peekTok(bool ShouldSkipSpace = true) {
106 : AsmToken Tok;
107 :
108 : MutableArrayRef<AsmToken> Buf(Tok);
109 286601 : size_t ReadCount = peekTokens(Buf, ShouldSkipSpace);
110 :
111 : assert(ReadCount == 1);
112 : (void)ReadCount;
113 :
114 : return Tok;
115 : }
116 :
117 : /// Look ahead an arbitrary number of tokens.
118 : virtual size_t peekTokens(MutableArrayRef<AsmToken> Buf,
119 : bool ShouldSkipSpace = true) = 0;
120 :
121 : /// Get the current error location
122 0 : SMLoc getErrLoc() {
123 0 : return ErrLoc;
124 : }
125 :
126 : /// Get the current error string
127 : const std::string &getErr() {
128 15 : return Err;
129 : }
130 :
131 : /// Get the kind of current token.
132 8943971 : AsmToken::TokenKind getKind() const { return getTok().getKind(); }
133 :
134 : /// Check if the current token has kind \p K.
135 13435922 : bool is(AsmToken::TokenKind K) const { return getTok().is(K); }
136 :
137 : /// Check if the current token has kind \p K.
138 7316664 : bool isNot(AsmToken::TokenKind K) const { return getTok().isNot(K); }
139 :
140 : /// Set whether spaces should be ignored by the lexer
141 420654 : void setSkipSpace(bool val) { SkipSpace = val; }
142 :
143 0 : bool getAllowAtInIdentifier() { return AllowAtInIdentifier; }
144 0 : void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; }
145 :
146 0 : void setCommentConsumer(AsmCommentConsumer *CommentConsumer) {
147 423 : this->CommentConsumer = CommentConsumer;
148 0 : }
149 : };
150 :
151 : } // end namespace llvm
152 :
153 : #endif // LLVM_MC_MCPARSER_MCASMLEXER_H
|