diff --git a/clang-tools-extra/clangd/Compiler.cpp b/clang-tools-extra/clangd/Compiler.cpp --- a/clang-tools-extra/clangd/Compiler.cpp +++ b/clang-tools-extra/clangd/Compiler.cpp @@ -63,6 +63,7 @@ // createInvocationFromCommandLine sets DisableFree. CI->getFrontendOpts().DisableFree = false; CI->getLangOpts()->CommentOpts.ParseAllComments = true; + CI->getPreprocessorOpts().DetailedRecord = true; return CI; } diff --git a/clang-tools-extra/clangd/SemanticHighlighting.h b/clang-tools-extra/clangd/SemanticHighlighting.h --- a/clang-tools-extra/clangd/SemanticHighlighting.h +++ b/clang-tools-extra/clangd/SemanticHighlighting.h @@ -40,6 +40,7 @@ Namespace, TemplateParameter, Primitive, + InactivePreprocessorBranch, Macro, LastKind = Macro diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -137,6 +137,29 @@ // the end of the Tokens). TokRef = TokRef.drop_front(Conflicting.size()); } + // Add inactive highlighting tokens. + const SourceManager &SM = AST.getSourceManager(); + for (const SourceRange &R : + AST.getPreprocessor().getPreprocessingRecord()->getSkippedRanges()) { + if (isInsideMainFile(R.getBegin(), SM)) { + // Create one token for each line in the skipped range, so it works + // with line-based diffing. + Position Begin = sourceLocToPosition(SM, R.getBegin()); + Position End = sourceLocToPosition(SM, R.getEnd()); + assert(Begin.line <= End.line); + for (int Line = Begin.line; Line <= End.line; ++Line) { + // Don't bother computing the offset for the end of the line, just use + // zero. The client will treat this highlighting kind specially, and + // highlight the entire line visually (i.e. not just to where the text + // on the line ends, but to the end of the screen). + NonConflicting.push_back( + {HighlightingKind::InactivePreprocessorBranch, + {Position{Line, 0}, Position{Line, 0}}}); + } + } + } + // Re-sort the tokens because that's what the diffing expects. + llvm::sort(NonConflicting); return NonConflicting; } @@ -345,6 +368,8 @@ return OS << "TemplateParameter"; case HighlightingKind::Primitive: return OS << "Primitive"; + case HighlightingKind::InactivePreprocessorBranch: + return OS << "InactivePreprocessorBranch"; case HighlightingKind::Macro: return OS << "Macro"; } @@ -474,6 +499,8 @@ return "entity.name.type.template.cpp"; case HighlightingKind::Primitive: return "storage.type.primitive.cpp"; + case HighlightingKind::InactivePreprocessorBranch: + return "meta.disabled"; case HighlightingKind::Macro: return "entity.name.function.preprocessor.cpp"; } diff --git a/clang-tools-extra/clangd/test/semantic-highlighting.test b/clang-tools-extra/clangd/test/semantic-highlighting.test --- a/clang-tools-extra/clangd/test/semantic-highlighting.test +++ b/clang-tools-extra/clangd/test/semantic-highlighting.test @@ -50,6 +50,9 @@ # CHECK-NEXT: "storage.type.primitive.cpp" # CHECK-NEXT: ], # CHECK-NEXT: [ +# CHECK-NEXT: "meta.disabled" +# CHECK-NEXT: ], +# CHECK-NEXT: [ # CHECK-NEXT: "entity.name.function.preprocessor.cpp" # CHECK-NEXT: ] # CHECK-NEXT: ]