1 //===--- SourceMgrUtils.cpp - SourceMgr LSP Utils -------------------------===//
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 #include "SourceMgrUtils.h"
10 
11 using namespace mlir;
12 using namespace mlir::lsp;
13 
14 /// Find the end of a string whose contents start at the given `curPtr`. Returns
15 /// the position at the end of the string, after a terminal or invalid character
16 /// (e.g. `"` or `\0`).
17 static const char *lexLocStringTok(const char *curPtr) {
18   while (char c = *curPtr++) {
19     // Check for various terminal characters.
20     if (StringRef("\"\n\v\f").contains(c))
21       return curPtr;
22 
23     // Check for escape sequences.
24     if (c == '\\') {
25       // Check a few known escapes and \xx hex digits.
26       if (*curPtr == '"' || *curPtr == '\\' || *curPtr == 'n' || *curPtr == 't')
27         ++curPtr;
28       else if (llvm::isHexDigit(*curPtr) && llvm::isHexDigit(curPtr[1]))
29         curPtr += 2;
30       else
31         return curPtr;
32     }
33   }
34 
35   // If we hit this point, we've reached the end of the buffer. Update the end
36   // pointer to not point past the buffer.
37   return curPtr - 1;
38 }
39 
40 SMRange lsp::convertTokenLocToRange(SMLoc loc) {
41   if (!loc.isValid())
42     return SMRange();
43   const char *curPtr = loc.getPointer();
44 
45   // Check if this is a string token.
46   if (*curPtr == '"') {
47     curPtr = lexLocStringTok(curPtr + 1);
48 
49     // Otherwise, default to handling an identifier.
50   } else {
51     // Return if the given character is a valid identifier character.
52     auto isIdentifierChar = [](char c) {
53       return isalnum(c) || c == '$' || c == '.' || c == '_' || c == '-';
54     };
55 
56     while (*curPtr && isIdentifierChar(*(++curPtr)))
57       continue;
58   }
59 
60   return SMRange(loc, SMLoc::getFromPointer(curPtr));
61 }
62