From e237520a8f5006692e25d7e5da7271f1c9832491 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Mon, 9 Sep 2019 14:33:10 +0000 Subject: [PATCH] [clangd] Add a new highlighting kind for typedefs Summary: We still attempt to highlight them as underlying types, but fallback to the generic 'typedef' highlighting kind if the underlying type is too complicated. Reviewers: hokein Reviewed By: hokein Subscribers: nridge, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D67290 llvm-svn: 371402 --- clang-tools-extra/clangd/SemanticHighlighting.cpp | 38 +++++++++++++++++----- clang-tools-extra/clangd/SemanticHighlighting.h | 1 + .../clangd/test/semantic-highlighting.test | 11 ++++--- .../clangd/unittests/SemanticHighlightingTests.cpp | 16 +++++---- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp index b5f1c40..5744e86 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -17,6 +17,7 @@ #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" +#include "clang/Basic/SourceLocation.h" #include namespace clang { @@ -125,13 +126,12 @@ public: } bool VisitTypedefNameDecl(TypedefNameDecl *TD) { - if (const auto *TSI = TD->getTypeSourceInfo()) - addType(TD->getLocation(), TSI->getTypeLoc().getTypePtr()); + addTokenForTypedef(TD->getLocation(), TD); return true; } bool VisitTypedefTypeLoc(TypedefTypeLoc TL) { - addType(TL.getBeginLoc(), TL.getTypePtr()); + addTokenForTypedef(TL.getBeginLoc(), TL.getTypedefNameDecl()); return true; } @@ -182,17 +182,35 @@ public: } private: - void addType(SourceLocation Loc, const Type *TP) { - if (!TP) + void addTokenForTypedef(SourceLocation Loc, const TypedefNameDecl *TD) { + auto *TSI = TD->getTypeSourceInfo(); + if (!TSI) + return; + // Try to highlight as underlying type. + if (addType(Loc, TSI->getType().getTypePtrOrNull())) return; - if (TP->isBuiltinType()) + // Fallback to the typedef highlighting kind. + addToken(Loc, HighlightingKind::Typedef); + } + + bool addType(SourceLocation Loc, const Type *TP) { + if (!TP) + return false; + if (TP->isBuiltinType()) { // Builtins must be special cased as they do not have a TagDecl. addToken(Loc, HighlightingKind::Primitive); - if (auto *TD = dyn_cast(TP)) + return true; + } + if (auto *TD = dyn_cast(TP)) { // TemplateTypeParmType also do not have a TagDecl. addToken(Loc, TD->getDecl()); - if (auto *TD = TP->getAsTagDecl()) + return true; + } + if (auto *TD = TP->getAsTagDecl()) { addToken(Loc, TD); + return true; + } + return false; } void addToken(SourceLocation Loc, const NamedDecl *D) { @@ -379,6 +397,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingKind K) { return OS << "Enum"; case HighlightingKind::EnumConstant: return OS << "EnumConstant"; + case HighlightingKind::Typedef: + return OS << "Typedef"; case HighlightingKind::Namespace: return OS << "Namespace"; case HighlightingKind::TemplateParameter: @@ -506,6 +526,8 @@ llvm::StringRef toTextMateScope(HighlightingKind Kind) { return "entity.name.type.enum.cpp"; case HighlightingKind::EnumConstant: return "variable.other.enummember.cpp"; + case HighlightingKind::Typedef: + return "entity.name.type.typedef.cpp"; case HighlightingKind::Namespace: return "entity.name.namespace.cpp"; case HighlightingKind::TemplateParameter: diff --git a/clang-tools-extra/clangd/SemanticHighlighting.h b/clang-tools-extra/clangd/SemanticHighlighting.h index 930fcca..11c0564 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.h +++ b/clang-tools-extra/clangd/SemanticHighlighting.h @@ -36,6 +36,7 @@ enum class HighlightingKind { Class, Enum, EnumConstant, + Typedef, Namespace, TemplateParameter, Primitive, diff --git a/clang-tools-extra/clangd/test/semantic-highlighting.test b/clang-tools-extra/clangd/test/semantic-highlighting.test index 005d01c..d802efb 100644 --- a/clang-tools-extra/clangd/test/semantic-highlighting.test +++ b/clang-tools-extra/clangd/test/semantic-highlighting.test @@ -38,6 +38,9 @@ # CHECK-NEXT: "variable.other.enummember.cpp" # CHECK-NEXT: ], # CHECK-NEXT: [ +# CHECK-NEXT: "entity.name.type.typedef.cpp" +# CHECK-NEXT: ], +# CHECK-NEXT: [ # CHECK-NEXT: "entity.name.namespace.cpp" # CHECK-NEXT: ], # CHECK-NEXT: [ @@ -58,7 +61,7 @@ # CHECK-NEXT: "lines": [ # CHECK-NEXT: { # CHECK-NEXT: "line": 0, -# CHECK-NEXT: "tokens": "AAAAAAADAA0AAAAEAAEAAA==" +# CHECK-NEXT: "tokens": "AAAAAAADAA4AAAAEAAEAAA==" # CHECK-NEXT: } # CHECK-NEXT: ], # CHECK-NEXT: "textDocument": { @@ -73,11 +76,11 @@ # CHECK-NEXT: "lines": [ # CHECK-NEXT: { # CHECK-NEXT: "line": 0, -# CHECK-NEXT: "tokens": "AAAAAAADAA0AAAAEAAEAAA==" +# CHECK-NEXT: "tokens": "AAAAAAADAA4AAAAEAAEAAA==" # CHECK-NEXT: } # CHECK-NEXT: { # CHECK-NEXT: "line": 1, -# CHECK-NEXT: "tokens": "AAAAAAADAA0AAAAEAAEAAA==" +# CHECK-NEXT: "tokens": "AAAAAAADAA4AAAAEAAEAAA==" # CHECK-NEXT: } # CHECK-NEXT: ], # CHECK-NEXT: "textDocument": { @@ -92,7 +95,7 @@ # CHECK-NEXT: "lines": [ # CHECK-NEXT: { # CHECK-NEXT: "line": 1, -# CHECK-NEXT: "tokens": "AAAAAAADAA0AAAAEAAEAAA==" +# CHECK-NEXT: "tokens": "AAAAAAADAA4AAAAEAAEAAA==" # CHECK-NEXT: } # CHECK-NEXT: ], # CHECK-NEXT: "textDocument": { diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp index 92e6256..abc0f4e 100644 --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -496,12 +496,16 @@ TEST(SemanticHighlighting, GetsCorrectTokens) { typedef $TemplateParameter[[T]] $TemplateParameter[[TemplateParam2]]; using $Primitive[[IntType]] = $Primitive[[int]]; - // These typedefs are not yet highlighted, their types are complicated. - using Pointer = $TemplateParameter[[T]] *; - using LVReference = $TemplateParameter[[T]] &; - using RVReference = $TemplateParameter[[T]]&&; - using Array = $TemplateParameter[[T]]*[3]; - using MemberPointer = $Primitive[[int]] (A::*)($Primitive[[int]]); + using $Typedef[[Pointer]] = $TemplateParameter[[T]] *; + using $Typedef[[LVReference]] = $TemplateParameter[[T]] &; + using $Typedef[[RVReference]] = $TemplateParameter[[T]]&&; + using $Typedef[[Array]] = $TemplateParameter[[T]]*[3]; + using $Typedef[[MemberPointer]] = $Primitive[[int]] (A::*)($Primitive[[int]]); + + // Use various previously defined typedefs in a function type. + $Primitive[[void]] $Method[[func]]( + $Typedef[[Pointer]], $Typedef[[LVReference]], $Typedef[[RVReference]], + $Typedef[[Array]], $Typedef[[MemberPointer]]); }; )cpp"}; for (const auto &TestCase : TestCases) { -- 2.7.4