12#include "llvm/ADT/StringExtras.h"
13#include "llvm/ADT/StringSwitch.h"
14#include "llvm/Support/SourceMgr.h"
25 getKind() == code_complete_string);
30 bytes = bytes.drop_front().drop_back();
31 else if (
is(string_block))
32 bytes = bytes.drop_front(2).drop_back(2);
35 result.reserve(bytes.size());
36 for (
unsigned i = 0, e = bytes.size(); i != e;) {
43 assert(i + 1 <= e &&
"invalid string should be caught by lexer");
60 assert(i + 1 <= e &&
"invalid string should be caught by lexer");
63 assert(llvm::isHexDigit(c1) && llvm::isHexDigit(c2) &&
"invalid escape");
64 result.push_back((llvm::hexDigitValue(c1) << 4) | llvm::hexDigitValue(c2));
76 : srcMgr(mgr), diagEngine(diagEngine), addedHandlerToDiagEngine(
false),
77 codeCompletionLocation(
nullptr) {
78 curBufferID = mgr.getMainFileID();
79 curBuffer = srcMgr.getMemoryBuffer(curBufferID)->getBuffer();
80 curPtr = curBuffer.begin();
83 if (codeCompleteContext) {
84 codeCompletionLocation =
90 if (!diagEngine.getHandlerFn()) {
91 diagEngine.setHandlerFn([&](const ast::Diagnostic &diag) {
92 srcMgr.PrintMessage(diag.getLocation().Start, diag.getSeverity(),
94 for (const ast::Diagnostic ¬e : diag.getNotes())
95 srcMgr.PrintMessage(note.getLocation().Start, note.getSeverity(),
98 addedHandlerToDiagEngine =
true;
103 if (addedHandlerToDiagEngine)
104 diagEngine.setHandlerFn(
nullptr);
108 std::string includedFile;
110 srcMgr.AddIncludeFile(filename.str(), includeLoc.End, includedFile);
114 curBufferID = bufferID;
115 curBuffer = srcMgr.getMemoryBuffer(curBufferID)->getBuffer();
116 curPtr = curBuffer.begin();
121 diagEngine.emitError(loc, msg);
126 diagEngine.emitError(loc, msg)->attachNote(note, noteLoc);
131 SMRange(SMLoc::getFromPointer(loc), SMLoc::getFromPointer(loc + 1)), msg);
134int Lexer::getNextChar() {
135 char curChar = *curPtr++;
138 return static_cast<unsigned char>(curChar);
142 if (curPtr - 1 != curBuffer.end())
154 if ((*curPtr ==
'\n' || (*curPtr ==
'\r')) && *curPtr != curChar)
162 const char *tokStart = curPtr;
165 if (tokStart == codeCompletionLocation)
169 int curChar = getNextChar();
173 if (isalpha(curChar) || curChar ==
'_')
174 return lexIdentifier(tokStart);
177 return emitError(tokStart,
"unexpected character");
183 SMLoc parentIncludeLoc = srcMgr.getParentIncludeLoc(curBufferID);
184 if (parentIncludeLoc.isValid()) {
185 curBufferID = srcMgr.FindBufferContainingLoc(parentIncludeLoc);
186 curBuffer = srcMgr.getMemoryBuffer(curBufferID)->getBuffer();
187 curPtr = parentIncludeLoc.getPointer();
195 if (*curPtr ==
'>') {
199 return emitError(tokStart,
"unexpected character");
207 if (*curPtr ==
'>') {
215 if (*curPtr ==
'{') {
217 return lexString(tokStart,
true);
236 if (*curPtr ==
'/') {
240 return emitError(tokStart,
"unexpected character");
250 return lexDirective(tokStart);
252 return lexString(tokStart,
false);
264 return lexNumber(tokStart);
270void Lexer::lexComment() {
272 assert(*curPtr ==
'/');
283 if (curPtr - 1 == curBuffer.end()) {
295Token Lexer::lexDirective(
const char *tokStart) {
297 while (isalnum(*curPtr) || *curPtr ==
'_')
300 StringRef str(tokStart, curPtr - tokStart);
304Token Lexer::lexIdentifier(
const char *tokStart) {
306 while (isalnum(*curPtr) || *curPtr ==
'_')
310 StringRef str(tokStart, curPtr - tokStart);
334 return Token(kind, str);
337Token Lexer::lexNumber(
const char *tokStart) {
338 assert(isdigit(curPtr[-1]));
341 while (isdigit(*curPtr))
347Token Lexer::lexString(
const char *tokStart,
bool isStringBlock) {
354 if (curPtr == codeCompletionLocation) {
356 tokStart + (isStringBlock ? 2 : 1));
369 if (!isStringBlock || *curPtr !=
']')
376 if (curPtr - 1 != curBuffer.end())
380 StringRef expectedEndStr = isStringBlock ?
"}]" :
"\"";
382 "expected '" + expectedEndStr +
"' in string literal");
390 return emitError(curPtr - 1,
"expected '\"' in string literal");
395 if (*curPtr ==
'"' || *curPtr ==
'\\' || *curPtr ==
'n' ||
398 }
else if (llvm::isHexDigit(*curPtr) && llvm::isHexDigit(curPtr[1])) {
402 return emitError(curPtr - 1,
"unknown escape in string literal");
false
Parses a map_entries map type from a string format back into its numeric value.
Lexer(const llvm::SourceMgr &sourceMgr, MLIRContext *context, AsmParserCodeCompleteContext *codeCompleteContext)
std::string getStringValue() const
Given a token containing a string literal, return its value, including removing the quote characters ...
StringRef getSpelling() const
This class provides an abstract interface into the parser for hooking in code completion events.
SMLoc getCodeCompleteLoc() const
Return the location used to provide code completion.
Token emitError(SMRange loc, const Twine &msg)
Emit an error to the lexer with the given location and message.
Token emitErrorAndNote(SMRange loc, const Twine &msg, SMRange noteLoc, const Twine ¬e)
Token lexToken()
Lex the next token and return it.
LogicalResult pushInclude(StringRef filename, SMRange includeLoc)
Push an include of the given file.
@ code_complete_string
Token signifying a code completion location within a string.
@ code_complete
Token signifying a code completion location.
@ less
Paired punctuation.
@ kw_Attr
General keywords.
This class manages the construction and emission of PDLL diagnostics.
Include the generated interface declarations.
llvm::StringSwitch< T, R > StringSwitch