#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/SourceLocation.h"
#include <algorithm>
namespace clang {
}
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;
}
}
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<TemplateTypeParmType>(TP))
+ return true;
+ }
+ if (auto *TD = dyn_cast<TemplateTypeParmType>(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) {
return OS << "Enum";
case HighlightingKind::EnumConstant:
return OS << "EnumConstant";
+ case HighlightingKind::Typedef:
+ return OS << "Typedef";
case HighlightingKind::Namespace:
return OS << "Namespace";
case HighlightingKind::TemplateParameter:
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:
# 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: [
# CHECK-NEXT: "lines": [
# CHECK-NEXT: {
# CHECK-NEXT: "line": 0,
-# CHECK-NEXT: "tokens": "AAAAAAADAA0AAAAEAAEAAA=="
+# CHECK-NEXT: "tokens": "AAAAAAADAA4AAAAEAAEAAA=="
# CHECK-NEXT: }
# CHECK-NEXT: ],
# CHECK-NEXT: "textDocument": {
# 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": {
# CHECK-NEXT: "lines": [
# CHECK-NEXT: {
# CHECK-NEXT: "line": 1,
-# CHECK-NEXT: "tokens": "AAAAAAADAA0AAAAEAAEAAA=="
+# CHECK-NEXT: "tokens": "AAAAAAADAA4AAAAEAAEAAA=="
# CHECK-NEXT: }
# CHECK-NEXT: ],
# CHECK-NEXT: "textDocument": {
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) {