aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Lex/Preprocessor.cpp
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2024-01-27 17:52:20 +0100
committerGitHub <noreply@github.com>2024-01-27 17:52:20 +0100
commit718aac9f7a19227b5c5ec85819a3a5ae24ce32e1 (patch)
tree5dab18c92e82d2c42f80de26908f0a1835e67a0c /clang/lib/Lex/Preprocessor.cpp
parent863b2c84c0fbcfb02d969fa36af4932d410a827b (diff)
downloadllvm-718aac9f7a19227b5c5ec85819a3a5ae24ce32e1.zip
llvm-718aac9f7a19227b5c5ec85819a3a5ae24ce32e1.tar.gz
llvm-718aac9f7a19227b5c5ec85819a3a5ae24ce32e1.tar.bz2
[clang][Diagnostics] Highlight code snippets (#66514)
Add some primitive syntax highlighting to our code snippet output. This adds "checkpoints" to the Preprocessor, which we can use to start lexing from. When printing a code snippet, we lex from the nearest checkpoint and highlight the tokens based on their token type.
Diffstat (limited to 'clang/lib/Lex/Preprocessor.cpp')
-rw-r--r--clang/lib/Lex/Preprocessor.cpp24
1 files changed, 24 insertions, 0 deletions
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index 7fdb5d4c..031ed1e 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -72,6 +72,9 @@
using namespace clang;
+/// Minimum distance between two check points, in tokens.
+static constexpr unsigned CheckPointStepSize = 1024;
+
LLVM_INSTANTIATE_REGISTRY(PragmaHandlerRegistry)
ExternalPreprocessorSource::~ExternalPreprocessorSource() = default;
@@ -954,6 +957,11 @@ void Preprocessor::Lex(Token &Result) {
}
}
+ if (CurLexer && ++CheckPointCounter == CheckPointStepSize) {
+ CheckPoints[CurLexer->getFileID()].push_back(CurLexer->BufferPtr);
+ CheckPointCounter = 0;
+ }
+
LastTokenWasAt = Result.is(tok::at);
--LexLevel;
@@ -1558,3 +1566,19 @@ void Preprocessor::createPreprocessingRecord() {
Record = new PreprocessingRecord(getSourceManager());
addPPCallbacks(std::unique_ptr<PPCallbacks>(Record));
}
+
+const char *Preprocessor::getCheckPoint(FileID FID, const char *Start) const {
+ if (auto It = CheckPoints.find(FID); It != CheckPoints.end()) {
+ const SmallVector<const char *> &FileCheckPoints = It->second;
+ const char *Last = nullptr;
+ // FIXME: Do better than a linear search.
+ for (const char *P : FileCheckPoints) {
+ if (P > Start)
+ break;
+ Last = P;
+ }
+ return Last;
+ }
+
+ return nullptr;
+}