diff options
author | Timm Baeder <tbaeder@redhat.com> | 2024-01-27 17:52:20 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-27 17:52:20 +0100 |
commit | 718aac9f7a19227b5c5ec85819a3a5ae24ce32e1 (patch) | |
tree | 5dab18c92e82d2c42f80de26908f0a1835e67a0c /clang/lib/Lex/Preprocessor.cpp | |
parent | 863b2c84c0fbcfb02d969fa36af4932d410a827b (diff) | |
download | llvm-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.cpp | 24 |
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; +} |