17#include "clang/Basic/FileManager.h"
18#include "clang/Basic/SourceManager.h"
19#include "clang/Lex/Lexer.h"
20#include "llvm/ADT/StringSet.h"
21#include "llvm/Support/MemoryBuffer.h"
33#define KEYWORD(X, N) keywords.insert(#X);
34#include "clang/Basic/TokenKinds.def"
54 const clang::Token &token, llvm::StringRef tok_str,
56 using namespace clang;
58 if (token.is(tok::comment)) {
60 in_pp_directive =
false;
62 }
else if (in_pp_directive || token.getKind() == tok::hash) {
64 in_pp_directive =
true;
67 }
else if (tok::isStringLiteral(token.getKind()))
69 else if (tok::isLiteral(token.getKind()))
74 switch (token.getKind()) {
75 case tok::raw_identifier:
103 case tok::minusminus:
104 case tok::minusequal:
107 case tok::exclaimequal:
109 case tok::slashequal:
111 case tok::percentequal:
115 case tok::lesslessequal:
118 case tok::greatergreater:
119 case tok::greaterequal:
120 case tok::greatergreaterequal:
122 case tok::caretequal:
128 case tok::equalequal:
137 llvm::StringRef line,
138 std::optional<size_t> cursor_pos,
139 llvm::StringRef previous_lines,
141 using namespace clang;
143 FileSystemOptions file_opts;
144 FileManager file_mgr(file_opts,
153 llvm::StringRef line_ending =
"";
156 if (line.consume_back(
"\r\n"))
157 line_ending =
"\r\n";
158 else if (line.consume_back(
"\n"))
160 else if (line.consume_back(
"\r"))
163 unsigned line_number = previous_lines.count(
'\n') + 1U;
167 std::string full_source = previous_lines.str() + line.str();
168 DiagnosticOptions diags_opts;
169 DiagnosticsEngine diags(DiagnosticIDs::create(), diags_opts);
170 clang::SourceManager SM(diags, file_mgr);
171 auto buf = llvm::MemoryBuffer::getMemBuffer(full_source);
173 FileID FID = SM.createFileID(buf->getMemBufferRef());
180 Opts.CPlusPlus17 =
true;
181 Opts.LineComment =
true;
183 Lexer lex(FID, buf->getMemBufferRef(), SM, Opts);
185 lex.SetKeepWhitespaceMode(
true);
188 bool in_pp_directive =
false;
191 bool found_user_line =
false;
194 bool highlighted_cursor =
false;
199 exit = lex.LexFromRawLexer(token);
201 bool invalid =
false;
202 unsigned current_line_number =
203 SM.getSpellingLineNumber(token.getLocation(), &invalid);
204 if (current_line_number != line_number)
206 found_user_line =
true;
214 unsigned start = SM.getSpellingColumnNumber(token.getLocation(), &invalid);
221 if (token.isAnnotation())
225 llvm::StringRef tok_str = line.substr(start, token.getLength());
233 llvm::StringRef to_print = tok_str;
235 auto end = start + token.getLength();
236 if (cursor_pos && end > *cursor_pos && !highlighted_cursor) {
237 highlighted_cursor =
true;
246 color.
Apply(result, to_print);
250 result << line_ending;
256 if (!found_user_line) {
258 assert(
false &&
"We couldn't find the user line in the input file?");
static HighlightStyle::ColorStyle determineClangStyle(const ClangHighlighter &highlighter, const clang::Token &token, llvm::StringRef tok_str, const HighlightStyle &options, bool &in_pp_directive)
Determines which style should be applied to the given token.
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
static llvm::StringRef GetPluginNameStatic()
static Highlighter * CreateInstance(lldb::LanguageType language)
void Highlight(const HighlightStyle &options, llvm::StringRef line, std::optional< size_t > cursor_pos, llvm::StringRef previous_lines, Stream &s) const override
Highlights the given line.
bool isKeyword(llvm::StringRef token) const
Returns true if the given string represents a keywords in any Clang supported language.
static FileSystem & Instance()
A pair of strings that should be placed around a certain token.
void Apply(Stream &s, llvm::StringRef value) const
Applies this style to the given value.
static bool LanguageIsCFamily(lldb::LanguageType language)
Equivalent to LanguageIsC||LanguageIsObjC||LanguageIsCPlusPlus.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
A class that represents a running process on the host machine.
LanguageType
Programming language type.
Represents style that the highlighter should apply to the given source code.
ColorStyle square_brackets
Matches '[' or ']'.
ColorStyle comment
Matches any comments in the language.
ColorStyle braces
Matches '{' or '}'.
ColorStyle scalar_literal
Matches scalar value literals like '42' or '0.1'.
ColorStyle comma
Matches commas: ','.
ColorStyle pp_directive
Matches directives to a preprocessor (if the language has any).
ColorStyle operators
Matches operators like '+', '-', '', '&', '='.
ColorStyle string_literal
Matches any string or character literals in the language: "foo" or 'f'.
ColorStyle keyword
Matches all reserved keywords in the language.
ColorStyle parentheses
Matches '(' or ')'.
ColorStyle selected
The style for the token which is below the cursor of the user.
ColorStyle identifier
Matches identifiers to variable or functions.
ColorStyle colon
Matches one colon: ':'.