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.AllowLiteralDigitSeparator =
true;
182 Opts.LineComment =
true;
184 Lexer lex(FID, buf->getMemBufferRef(), SM, Opts);
186 lex.SetKeepWhitespaceMode(
true);
189 bool in_pp_directive =
false;
192 bool found_user_line =
false;
195 bool highlighted_cursor =
false;
200 exit = lex.LexFromRawLexer(token);
202 bool invalid =
false;
203 unsigned current_line_number =
204 SM.getSpellingLineNumber(token.getLocation(), &invalid);
205 if (current_line_number != line_number)
207 found_user_line =
true;
215 unsigned start = SM.getSpellingColumnNumber(token.getLocation(), &invalid);
222 if (token.isAnnotation())
226 llvm::StringRef tok_str = line.substr(start, token.getLength());
234 llvm::StringRef to_print = tok_str;
236 auto end = start + token.getLength();
237 if (cursor_pos && end > *cursor_pos && !highlighted_cursor) {
238 highlighted_cursor =
true;
247 color.
Apply(result, to_print);
251 result << line_ending;
257 if (!found_user_line) {
259 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.
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.