Index: clang-tools-extra/trunk/clangd/SemanticHighlighting.h =================================================================== --- clang-tools-extra/trunk/clangd/SemanticHighlighting.h +++ clang-tools-extra/trunk/clangd/SemanticHighlighting.h @@ -38,6 +38,7 @@ Namespace, TemplateParameter, Primitive, + Macro, NumKinds, }; Index: clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp =================================================================== --- clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp +++ clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp @@ -24,16 +24,20 @@ class HighlightingTokenCollector : public RecursiveASTVisitor { std::vector Tokens; - ASTContext &Ctx; - const SourceManager &SM; + ParsedAST * public: - HighlightingTokenCollector(ParsedAST &AST) - : Ctx(AST.getASTContext()), SM(AST.getSourceManager()) {} + HighlightingTokenCollector(ParsedAST &AST) : AST(AST) {} std::vector collectTokens() { Tokens.clear(); - TraverseAST(Ctx); + TraverseAST(AST.getASTContext()); + // Add highlightings for macro expansions as they are not traversed by the + // visitor. + // FIXME: Should add highlighting to the macro definitions as well. But this + // information is not collected in ParsedAST right now. + for (const SourceLocation &L : AST.getMainFileExpansions()) + addToken(L, HighlightingKind::Macro); // Initializer lists can give duplicates of tokens, therefore all tokens // must be deduplicated. llvm::sort(Tokens); @@ -264,6 +268,7 @@ } void addToken(SourceLocation Loc, HighlightingKind Kind) { + const auto &SM = AST.getSourceManager(); if (Loc.isMacroID()) { // Only intereseted in highlighting arguments in macros (DEF_X(arg)). if (!SM.isMacroArgExpansion(Loc)) @@ -279,7 +284,7 @@ if (!isInsideMainFile(Loc, SM)) return; - auto R = getTokenRange(SM, Ctx.getLangOpts(), Loc); + auto R = getTokenRange(SM, AST.getASTContext().getLangOpts(), Loc); if (!R) { // R should always have a value, if it doesn't something is very wrong. elog("Tried to add semantic token with an invalid range"); @@ -466,6 +471,8 @@ return "entity.name.type.template.cpp"; case HighlightingKind::Primitive: return "storage.type.primitive.cpp"; + case HighlightingKind::Macro: + return "entity.name.function.preprocessor.cpp"; case HighlightingKind::NumKinds: llvm_unreachable("must not pass NumKinds to the function"); } Index: clang-tools-extra/trunk/clangd/test/semantic-highlighting.test =================================================================== --- clang-tools-extra/trunk/clangd/test/semantic-highlighting.test +++ clang-tools-extra/trunk/clangd/test/semantic-highlighting.test @@ -45,6 +45,9 @@ # CHECK-NEXT: ], # CHECK-NEXT: [ # CHECK-NEXT: "storage.type.primitive.cpp" +# CHECK-NEXT: ], +# CHECK-NEXT: [ +# CHECK-NEXT: "entity.name.function.preprocessor.cpp" # CHECK-NEXT: ] # CHECK-NEXT: ] # CHECK-NEXT: }, Index: clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp =================================================================== --- clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp +++ clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp @@ -47,7 +47,8 @@ {HighlightingKind::Method, "Method"}, {HighlightingKind::StaticMethod, "StaticMethod"}, {HighlightingKind::TemplateParameter, "TemplateParameter"}, - {HighlightingKind::Primitive, "Primitive"}}; + {HighlightingKind::Primitive, "Primitive"}, + {HighlightingKind::Macro, "Macro"}}; std::vector ExpectedTokens; for (const auto &KindString : KindToString) { std::vector Toks = makeHighlightingTokens( @@ -391,9 +392,9 @@ R"cpp( #define DEF_MULTIPLE(X) namespace X { class X { int X; }; } #define DEF_CLASS(T) class T {}; - DEF_MULTIPLE(XYZ); - DEF_MULTIPLE(XYZW); - DEF_CLASS($Class[[A]]) + $Macro[[DEF_MULTIPLE]](XYZ); + $Macro[[DEF_MULTIPLE]](XYZW); + $Macro[[DEF_CLASS]]($Class[[A]]) #define MACRO_CONCAT(X, V, T) T foo##X = V #define DEF_VAR(X, V) int X = V #define DEF_VAR_T(T, X, V) T X = V @@ -404,26 +405,27 @@ #define SOME_NAME_SET variable2 = 123 #define INC_VAR(X) X += 2 $Primitive[[void]] $Function[[foo]]() { - DEF_VAR($LocalVariable[[X]], 123); - DEF_VAR_REV(908, $LocalVariable[[XY]]); - $Primitive[[int]] CPY( $LocalVariable[[XX]] ); - DEF_VAR_TYPE($Class[[A]], $LocalVariable[[AA]]); - $Primitive[[double]] SOME_NAME; - $Primitive[[int]] SOME_NAME_SET; + $Macro[[DEF_VAR]]($LocalVariable[[X]], 123); + $Macro[[DEF_VAR_REV]](908, $LocalVariable[[XY]]); + $Primitive[[int]] $Macro[[CPY]]( $LocalVariable[[XX]] ); + $Macro[[DEF_VAR_TYPE]]($Class[[A]], $LocalVariable[[AA]]); + $Primitive[[double]] $Macro[[SOME_NAME]]; + $Primitive[[int]] $Macro[[SOME_NAME_SET]]; $LocalVariable[[variable]] = 20.1; - MACRO_CONCAT(var, 2, $Primitive[[float]]); - DEF_VAR_T($Class[[A]], CPY(CPY($LocalVariable[[Nested]])), - CPY($Class[[A]]())); - INC_VAR($LocalVariable[[variable]]); - } - $Primitive[[void]] SOME_NAME(); - DEF_VAR($Variable[[XYZ]], 567); - DEF_VAR_REV(756, $Variable[[AB]]); + $Macro[[MACRO_CONCAT]](var, 2, $Primitive[[float]]); + $Macro[[DEF_VAR_T]]($Class[[A]], $Macro[[CPY]]( + $Macro[[CPY]]($LocalVariable[[Nested]])), + $Macro[[CPY]]($Class[[A]]())); + $Macro[[INC_VAR]]($LocalVariable[[variable]]); + } + $Primitive[[void]] $Macro[[SOME_NAME]](); + $Macro[[DEF_VAR]]($Variable[[XYZ]], 567); + $Macro[[DEF_VAR_REV]](756, $Variable[[AB]]); #define CALL_FN(F) F(); #define DEF_FN(F) void F () - DEF_FN($Function[[g]]) { - CALL_FN($Function[[foo]]); + $Macro[[DEF_FN]]($Function[[g]]) { + $Macro[[CALL_FN]]($Function[[foo]]); } )cpp", R"cpp( @@ -433,8 +435,8 @@ $Primitive[[int]] $Variable[[y]]; $Primitive[[int]] $Function[[f]](); $Primitive[[void]] $Function[[foo]]() { - assert($Variable[[x]] != $Variable[[y]]); - assert($Variable[[x]] != $Function[[f]]()); + $Macro[[assert]]($Variable[[x]] != $Variable[[y]]); + $Macro[[assert]]($Variable[[x]] != $Function[[f]]()); } )cpp", R"cpp( @@ -470,8 +472,8 @@ // A separate test for macros in headers. checkHighlightings(R"cpp( #include "imp.h" - DEFINE_Y - DXYZ_Y(A); + $Macro[[DEFINE_Y]] + $Macro[[DXYZ_Y]](A); )cpp", {{"imp.h", R"cpp( #define DXYZ(X) class X {};