brintos

brintos / llvm-project-archived public Read only

0
0
Text · 55.7 KiB · 94cecce Raw
1323 lines · cpp
1//==- SemanticHighlightingTests.cpp - SemanticHighlighting tests-*- C++ -* -==//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "Annotations.h"10#include "Config.h"11#include "Protocol.h"12#include "SemanticHighlighting.h"13#include "SourceCode.h"14#include "TestTU.h"15#include "llvm/ADT/ArrayRef.h"16#include "llvm/ADT/STLExtras.h"17#include "llvm/ADT/StringRef.h"18#include "llvm/Support/Error.h"19#include "llvm/Support/ScopedPrinter.h"20#include "llvm/Support/raw_ostream.h"21#include "gmock/gmock.h"22#include <algorithm>23 24namespace clang {25namespace clangd {26namespace {27 28using testing::IsEmpty;29using testing::SizeIs;30 31/// Annotates the input code with provided semantic highlightings. Results look32/// something like:33///   class $Class[[X]] {34///     $Primitive[[int]] $Field[[a]] = 0;35///   };36std::string annotate(llvm::StringRef Input,37                     llvm::ArrayRef<HighlightingToken> Tokens) {38  assert(llvm::is_sorted(39      Tokens, [](const HighlightingToken &L, const HighlightingToken &R) {40        return L.R.start < R.R.start;41      }));42 43  std::string Buf;44  llvm::raw_string_ostream OS(Buf);45  unsigned NextChar = 0;46  for (auto &T : Tokens) {47    unsigned StartOffset = llvm::cantFail(positionToOffset(Input, T.R.start));48    unsigned EndOffset = llvm::cantFail(positionToOffset(Input, T.R.end));49    assert(StartOffset <= EndOffset);50    assert(NextChar <= StartOffset);51 52    bool hasDef =53        T.Modifiers & (1 << uint32_t(HighlightingModifier::Definition));54    bool hasDecl =55        T.Modifiers & (1 << uint32_t(HighlightingModifier::Declaration));56    EXPECT_TRUE(!hasDef || hasDecl);57 58    OS << Input.substr(NextChar, StartOffset - NextChar);59    OS << '$' << T.Kind;60    for (unsigned I = 0;61         I <= static_cast<uint32_t>(HighlightingModifier::LastModifier); ++I) {62      if (T.Modifiers & (1 << I)) {63        // _decl_def is common and redundant, just print _def instead.64        if (I != uint32_t(HighlightingModifier::Declaration) || !hasDef)65          OS << '_' << static_cast<HighlightingModifier>(I);66      }67    }68    OS << "[[" << Input.substr(StartOffset, EndOffset - StartOffset) << "]]";69    NextChar = EndOffset;70  }71  OS << Input.substr(NextChar);72  return std::move(OS.str());73}74 75void checkHighlightings(llvm::StringRef Code,76                        std::vector<std::pair</*FileName*/ llvm::StringRef,77                                              /*FileContent*/ llvm::StringRef>>78                            AdditionalFiles = {},79                        uint32_t ModifierMask = -1,80                        std::vector<std::string> AdditionalArgs = {}) {81  Annotations Test(Code);82  TestTU TU;83  TU.Code = std::string(Test.code());84 85  TU.ExtraArgs.push_back("-std=c++20");86  TU.ExtraArgs.push_back("-xobjective-c++");87  TU.ExtraArgs.insert(std::end(TU.ExtraArgs), std::begin(AdditionalArgs),88                      std::end(AdditionalArgs));89 90  for (auto File : AdditionalFiles)91    TU.AdditionalFiles.insert({File.first, std::string(File.second)});92  auto AST = TU.build();93  auto Actual =94      getSemanticHighlightings(AST, /*IncludeInactiveRegionTokens=*/true);95  for (auto &Token : Actual)96    Token.Modifiers &= ModifierMask;97 98  EXPECT_EQ(Code, annotate(Test.code(), Actual));99}100 101constexpr static uint32_t ScopeModifierMask =102    1 << unsigned(HighlightingModifier::FunctionScope) |103    1 << unsigned(HighlightingModifier::ClassScope) |104    1 << unsigned(HighlightingModifier::FileScope) |105    1 << unsigned(HighlightingModifier::GlobalScope);106 107TEST(SemanticHighlighting, GetsCorrectTokens) {108  const char *TestCases[] = {109      R"cpp(110      struct $Class_def[[AS]] {111        double $Field_decl[[SomeMember]];112      };113      struct {114      } $Variable_def[[S]];115      void $Function_def[[foo]](int $Parameter_def[[A]], $Class[[AS]] $Parameter_def[[As]]) {116        $Primitive_deduced_defaultLibrary[[auto]] $LocalVariable_def[[VeryLongVariableName]] = 12312;117        $Class[[AS]]     $LocalVariable_def[[AA]];118        $Primitive_deduced_defaultLibrary[[auto]] $LocalVariable_def[[L]] = $LocalVariable[[AA]].$Field[[SomeMember]] $Operator[[+]] $Parameter[[A]];119        auto $LocalVariable_def[[FN]] = [ $LocalVariable[[AA]]](int $Parameter_def[[A]]) -> void {};120        $LocalVariable[[FN]]$Operator_userDefined[[(]]12312$Operator_userDefined[[)]];121      }122    )cpp",123      R"cpp(124      void $Function_decl[[foo]](int);125      void $Function_decl[[Gah]]();126      void $Function_def[[foo]]() {127        auto $LocalVariable_def[[Bou]] = $Function[[Gah]];128      }129      struct $Class_def[[A]] {130        void $Method_decl[[abc]]();131      };132    )cpp",133      R"cpp(134      namespace $Namespace_decl[[abc]] {135        template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]136        struct $Class_def[[A]] {137          $TemplateParameter[[T]] $Field_decl[[t]];138        };139      }140      template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]141      struct $Class_def[[C]] : $Namespace[[abc]]::$Class[[A]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] {142        typename $TemplateParameter[[T]]::$Type_dependentName[[A]]* $Field_decl[[D]];143      };144      $Namespace[[abc]]::$Class[[A]]$Bracket[[<]]int$Bracket[[>]] $Variable_def[[AA]];145      typedef $Namespace[[abc]]::$Class[[A]]$Bracket[[<]]int$Bracket[[>]] $Class_decl[[AAA]];146      struct $Class_def[[B]] {147        $Class_decl_constrDestr[[B]]();148        ~$Class_decl_constrDestr[[B]]();149        void operator$Operator_decl[[<<]]($Class[[B]]);150        $Class[[AAA]] $Field_decl[[AA]];151      };152      $Class[[B]]::$Class_def_constrDestr[[B]]() {}153      $Class[[B]]::~$Class_def_constrDestr[[B]]() {}154      void $Function_def[[f]] () {155        $Class[[B]] $LocalVariable_def[[BB]] = $Class[[B]]();156        $LocalVariable[[BB]].~$Class_constrDestr[[B]]();157        $Class[[B]]();158      }159    )cpp",160      R"cpp(161      enum class $Enum_decl[[E]] {162        $EnumConstant_decl_readonly[[A]],163        $EnumConstant_decl_readonly[[B]],164      };165      enum $Enum_decl[[EE]] {166        $EnumConstant_decl_readonly[[Hi]],167      };168      struct $Class_def[[A]] {169        $Enum[[E]] $Field_decl[[EEE]];170        $Enum[[EE]] $Field_decl[[EEEE]];171      };172      int $Variable_def[[I]] = $EnumConstant_readonly[[Hi]];173      $Enum[[E]] $Variable_def[[L]] = $Enum[[E]]::$EnumConstant_readonly[[B]];174    )cpp",175      R"cpp(176      namespace $Namespace_decl[[abc]] {177        namespace {}178        namespace $Namespace_decl[[bcd]] {179          struct $Class_def[[A]] {};180          namespace $Namespace_decl[[cde]] {181            struct $Class_def[[A]] {182              enum class $Enum_decl[[B]] {183                $EnumConstant_decl_readonly[[Hi]],184              };185            };186          }187        }188      }189      using namespace $Namespace[[abc]]::$Namespace[[bcd]];190      namespace $Namespace_decl[[vwz]] =191            $Namespace[[abc]]::$Namespace[[bcd]]::$Namespace[[cde]];192      $Namespace[[abc]]::$Namespace[[bcd]]::$Class[[A]] $Variable_def[[AA]];193      $Namespace[[vwz]]::$Class[[A]]::$Enum[[B]] $Variable_def[[AAA]] =194            $Namespace[[vwz]]::$Class[[A]]::$Enum[[B]]::$EnumConstant_readonly[[Hi]];195      ::$Namespace[[vwz]]::$Class[[A]] $Variable_def[[B]];196      ::$Namespace[[abc]]::$Namespace[[bcd]]::$Class[[A]] $Variable_def[[BB]];197    )cpp",198      R"cpp(199      struct $Class_def[[D]] {200        double $Field_decl[[C]];201      };202      struct $Class_def[[A]] {203        double $Field_decl[[B]];204        $Class[[D]] $Field_decl[[E]];205        static double $StaticField_decl_static[[S]];206        static void $StaticMethod_def_static[[bar]]() {}207        void $Method_def[[foo]]() {208          $Field[[B]] $Operator[[=]] 123;209          this->$Field[[B]] $Operator[[=]] 156;210          this->$Method[[foo]]();211          $Method[[foo]]();212          $StaticMethod_static[[bar]]();213          $StaticField_static[[S]] $Operator[[=]] 90.1;214        }215      };216      void $Function_def[[foo]]() {217        $Class[[A]] $LocalVariable_def[[AA]];218        $LocalVariable[[AA]].$Field[[B]] $Operator[[+=]] 2;219        $LocalVariable[[AA]].$Method[[foo]]();220        $LocalVariable[[AA]].$Field[[E]].$Field[[C]];221        $Class[[A]]::$StaticField_static[[S]] $Operator[[=]] 90;222      }223    )cpp",224      R"cpp(225      struct $Class_def[[AA]] {226        int $Field_decl[[A]];227      };228      int $Variable_def[[B]];229      $Class[[AA]] $Variable_def[[A]]{$Variable[[B]]};230    )cpp",231      R"cpp(232      namespace $Namespace_decl[[a]] {233        struct $Class_def[[A]] {};234        typedef char $Primitive_decl[[C]];235      }236      typedef $Namespace[[a]]::$Class[[A]] $Class_decl[[B]];237      using $Class_decl[[BB]] = $Namespace[[a]]::$Class[[A]];238      enum class $Enum_decl[[E]] {};239      typedef $Enum[[E]] $Enum_decl[[C]];240      typedef $Enum[[C]] $Enum_decl[[CC]];241      using $Enum_decl[[CD]] = $Enum[[CC]];242      $Enum[[CC]] $Function_decl[[f]]($Class[[B]]);243      $Enum[[CD]] $Function_decl[[f]]($Class[[BB]]);244      typedef $Namespace[[a]]::$Primitive[[C]] $Primitive_decl[[PC]];245      typedef float $Primitive_decl[[F]];246    )cpp",247      R"cpp(248      template$Bracket[[<]]typename $TemplateParameter_def[[T]], typename = void$Bracket[[>]]249      class $Class_def[[A]] {250        $TemplateParameter[[T]] $Field_decl[[AA]];251        $TemplateParameter[[T]] $Method_decl[[foo]]();252      };253      template$Bracket[[<]]class $TemplateParameter_def[[TT]]$Bracket[[>]]254      class $Class_def[[B]] {255        $Class[[A]]$Bracket[[<]]$TemplateParameter[[TT]]$Bracket[[>]] $Field_decl[[AA]];256      };257      template$Bracket[[<]]class $TemplateParameter_def[[TT]], class $TemplateParameter_def[[GG]]$Bracket[[>]]258      class $Class_def[[BB]] {};259      template$Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]260      class $Class_def[[BB]]$Bracket[[<]]$TemplateParameter[[T]], int$Bracket[[>]] {};261      template$Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]262      class $Class_def[[BB]]$Bracket[[<]]$TemplateParameter[[T]], $TemplateParameter[[T]]*$Bracket[[>]] {};263 264      template$Bracket[[<]]template$Bracket[[<]]class$Bracket[[>]] class $TemplateParameter_def[[T]], class $TemplateParameter_def[[C]]$Bracket[[>]]265      $TemplateParameter[[T]]$Bracket[[<]]$TemplateParameter[[C]]$Bracket[[>]] $Function_decl[[f]]();266 267      template$Bracket[[<]]typename$Bracket[[>]]268      class $Class_def[[Foo]] {};269 270      template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]271      void $Function_decl[[foo]]($TemplateParameter[[T]] ...);272    )cpp",273      R"cpp(274      template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]275      struct $Class_def[[Tmpl]] {$TemplateParameter[[T]] $Field_decl[[x]] = 0;};276      extern template struct $Class_def[[Tmpl]]$Bracket[[<]]float$Bracket[[>]];277      template struct $Class_def[[Tmpl]]$Bracket[[<]]double$Bracket[[>]];278    )cpp",279      // This test is to guard against highlightings disappearing when using280      // conversion operators as their behaviour in the clang AST differ from281      // other CXXMethodDecls.282      R"cpp(283      class $Class_def[[Foo]] {};284      struct $Class_def[[Bar]] {285        explicit operator $Class[[Foo]]*() const;286        explicit operator int() const;287        operator $Class[[Foo]]();288      };289      void $Function_def[[f]]() {290        $Class[[Bar]] $LocalVariable_def[[B]];291        $Class[[Foo]] $LocalVariable_def[[F]] = $LocalVariable[[B]];292        $Class[[Foo]] *$LocalVariable_def[[FP]] = ($Class[[Foo]]*)$LocalVariable[[B]];293        int $LocalVariable_def[[I]] = (int)$LocalVariable[[B]];294      }295    )cpp",296      R"cpp(297      struct $Class_def[[B]] {};298      struct $Class_def[[A]] {299        $Class[[B]] $Field_decl[[BB]];300        $Class[[A]] &operator$Operator_decl[[=]]($Class[[A]] &&$Parameter_def[[O]]);301      };302 303      $Class[[A]] &$Class[[A]]::operator$Operator_def[[=]]($Class[[A]] &&$Parameter_def[[O]]) = default;304    )cpp",305      R"cpp(306      enum $Enum_decl[[En]] {307        $EnumConstant_decl_readonly[[EC]],308      };309      class $Class_def[[Foo]] {};310      class $Class_def[[Bar]] {311      public:312        $Class[[Foo]] $Field_decl[[Fo]];313        $Enum[[En]] $Field_decl[[E]];314        int $Field_decl[[I]];315        $Class_def_constrDestr[[Bar]] ($Class[[Foo]] $Parameter_def[[F]],316                $Enum[[En]] $Parameter_def[[E]])317        : $Field[[Fo]] ($Parameter[[F]]), $Field[[E]] ($Parameter[[E]]),318          $Field[[I]] (123) {}319      };320      class $Class_def[[Bar2]] : public $Class[[Bar]] {321        $Class_def_constrDestr[[Bar2]]() : $Class[[Bar]]($Class[[Foo]](), $EnumConstant_readonly[[EC]]) {}322      };323    )cpp",324      R"cpp(325      enum $Enum_decl[[E]] {326        $EnumConstant_decl_readonly[[E]],327      };328      class $Class_def[[Foo]] {};329      $Enum_deduced[[auto]] $Variable_def[[AE]] = $Enum[[E]]::$EnumConstant_readonly[[E]];330      $Class_deduced[[auto]] $Variable_def[[AF]] = $Class[[Foo]]();331      $Class_deduced[[decltype]](auto) $Variable_def[[AF2]] = $Class[[Foo]]();332      $Class_deduced[[auto]] *$Variable_def[[AFP]] = $Operator[[&]]$Variable[[AF]];333      $Enum_deduced[[auto]] &$Variable_def[[AER]] = $Variable[[AE]];334      $Primitive_deduced_defaultLibrary[[auto]] $Variable_def[[Form]] = 10.2 $Operator[[+]] 2 $Operator[[*]] 4;335      $Primitive_deduced_defaultLibrary[[decltype]]($Variable[[Form]]) $Variable_def[[F]] = 10;336      auto $Variable_def[[Fun]] = []()->void{};337    )cpp",338      R"cpp(339      class $Class_def[[G]] {};340      template$Bracket[[<]]$Class[[G]] *$TemplateParameter_def_readonly[[U]]$Bracket[[>]]341      class $Class_def[[GP]] {};342      template$Bracket[[<]]$Class[[G]] &$TemplateParameter_def_readonly[[U]]$Bracket[[>]]343      class $Class_def[[GR]] {};344      template$Bracket[[<]]int *$TemplateParameter_def_readonly[[U]]$Bracket[[>]]345      class $Class_def[[IP]] {346        void $Method_def[[f]]() {347          $Operator[[*]]$TemplateParameter_readonly[[U]] $Operator[[+=]] 5;348        }349      };350      template$Bracket[[<]]unsigned $TemplateParameter_def_readonly[[U]] = 2$Bracket[[>]]351      class $Class_def[[Foo]] {352        void $Method_def[[f]]() {353          for(int $LocalVariable_def[[I]] = 0;354            $LocalVariable[[I]] $Operator[[<]] $TemplateParameter_readonly[[U]];) {}355        }356      };357 358      $Class[[G]] $Variable_def[[L]];359      void $Function_def[[f]]() {360        $Class[[Foo]]$Bracket[[<]]123$Bracket[[>]] $LocalVariable_def[[F]];361        $Class[[GP]]$Bracket[[<]]$Operator[[&]]$Variable[[L]]$Bracket[[>]] $LocalVariable_def[[LL]];362        $Class[[GR]]$Bracket[[<]]$Variable[[L]]$Bracket[[>]] $LocalVariable_def[[LLL]];363      }364    )cpp",365      R"cpp(366      template$Bracket[[<]]typename $TemplateParameter_def[[T]],367        void ($TemplateParameter[[T]]::*$TemplateParameter_def_readonly[[method]])(int)$Bracket[[>]]368      struct $Class_def[[G]] {369        void $Method_def[[foo]](370            $TemplateParameter[[T]] *$Parameter_def[[O]]) {371          ($Parameter[[O]]$Operator_userDefined[[->*]]$TemplateParameter_readonly[[method]])(10);372 373        }374      };375      struct $Class_def[[F]] {376        void $Method_decl[[f]](int);377      };378      template$Bracket[[<]]void (*$TemplateParameter_def_readonly[[Func]])()$Bracket[[>]]379      struct $Class_def[[A]] {380        void $Method_def[[f]]() {381          ($Operator[[*]]$TemplateParameter_readonly[[Func]])();382        }383      };384 385      void $Function_def[[foo]]() {386        $Class[[F]] $LocalVariable_def[[FF]];387        $Class[[G]]$Bracket[[<]]$Class[[F]], $Operator[[&]]$Class[[F]]::$Method[[f]]$Bracket[[>]] $LocalVariable_def[[GG]];388        $LocalVariable[[GG]].$Method[[foo]]($Operator[[&]]$LocalVariable_usedAsMutablePointer[[FF]]);389        $Class[[A]]$Bracket[[<]]$Function[[foo]]$Bracket[[>]] $LocalVariable_def[[AA]];390      }391    )cpp",392      // Tokens that share a source range but have conflicting Kinds are not393      // highlighted.394      R"cpp(395      #define $Macro_decl[[DEF_MULTIPLE]](X) namespace X { class X { int X; }; }396      #define $Macro_decl[[DEF_CLASS]](T) class T {};397      // Preamble ends.398      $Macro[[DEF_MULTIPLE]](XYZ);399      $Macro[[DEF_MULTIPLE]](XYZW);400      $Macro[[DEF_CLASS]]($Class_def[[A]])401      #define $Macro_decl[[MACRO_CONCAT]](X, V, T) T foo##X = V402      #define $Macro_decl[[DEF_VAR]](X, V) int X = V403      #define $Macro_decl[[DEF_VAR_T]](T, X, V) T X = V404      #define $Macro_decl[[DEF_VAR_REV]](V, X) $Macro[[DEF_VAR]](X, V)405      #define $Macro_decl[[CPY]](X) X406      #define $Macro_decl[[DEF_VAR_TYPE]](X, Y) X Y407      #define $Macro_decl[[SOME_NAME]] variable408      #define $Macro_decl[[SOME_NAME_SET]] variable2 = 123409      #define $Macro_decl[[INC_VAR]](X) X += 2410      void $Function_def[[foo]]() {411        $Macro[[DEF_VAR]]($LocalVariable_def[[X]],  123);412        $Macro[[DEF_VAR_REV]](908, $LocalVariable_def[[XY]]);413        int $Macro[[CPY]]( $LocalVariable_def[[XX]] );414        $Macro[[DEF_VAR_TYPE]]($Class[[A]], $LocalVariable_def[[AA]]);415        double $Macro[[SOME_NAME]];416        int $Macro[[SOME_NAME_SET]];417        $LocalVariable[[variable]] $Operator[[=]] 20.1;418        $Macro[[MACRO_CONCAT]](var, 2, float);419        $Macro[[DEF_VAR_T]]($Class[[A]], $Macro[[CPY]](420              $Macro[[CPY]]($LocalVariable_def[[Nested]])),421            $Macro[[CPY]]($Class[[A]]()));422        $Macro[[INC_VAR]]($LocalVariable[[variable]]);423      }424      void $Macro[[SOME_NAME]]();425      $Macro[[DEF_VAR]]($Variable_def[[MMMMM]], 567);426      $Macro[[DEF_VAR_REV]](756, $Variable_def[[AB]]);427 428      #define $Macro_decl[[CALL_FN]](F) F();429      #define $Macro_decl[[DEF_FN]](F) void F ()430      $Macro[[DEF_FN]]($Function_def[[g]]) {431        $Macro[[CALL_FN]]($Function[[foo]]);432      }433    )cpp",434      R"cpp(435      #define $Macro_decl[[fail]](expr) expr436      #define $Macro_decl[[assert]](COND) if (!(COND)) { $Macro[[fail]]("assertion failed" #COND); }437      // Preamble ends.438      int $Variable_def[[x]];439      int $Variable_def[[y]];440      int $Function_decl[[f]]();441      void $Function_def[[foo]]() {442        $Macro[[assert]]($Variable[[x]] $Operator[[!=]] $Variable[[y]]);443        $Macro[[assert]]($Variable[[x]] $Operator[[!=]] $Function[[f]]());444      }445    )cpp",446      // highlighting all macro references447      R"cpp(448      #ifndef $Macro[[name]]449      #define $Macro_decl[[name]]450      #endif451 452      #define $Macro_decl[[test]]453      #undef $Macro[[test]]454      #ifdef $Macro[[test]]455      #endif456 457      #if defined($Macro[[test]])458      #endif459    )cpp",460      R"cpp(461      struct $Class_def[[S]] {462        float $Field_decl[[Value]];463        $Class[[S]] *$Field_decl[[Next]];464      };465      $Class[[S]] $Variable_def[[Global]][2] = {$Class[[S]](), $Class[[S]]()};466      auto [$Variable_decl[[G1]], $Variable_decl[[G2]]] = $Variable[[Global]];467      void $Function_def[[f]]($Class[[S]] $Parameter_def[[P]]) {468        int $LocalVariable_def[[A]][2] = {1,2};469        auto [$LocalVariable_decl[[B1]], $LocalVariable_decl[[B2]]] = $LocalVariable[[A]];470        auto [$LocalVariable_decl[[G1]], $LocalVariable_decl[[G2]]] = $Variable[[Global]];471        $Class_deduced[[auto]] [$LocalVariable_decl[[P1]], $LocalVariable_decl[[P2]]] = $Parameter[[P]];472        // Highlights references to BindingDecls.473        $LocalVariable[[B1]]$Operator[[++]];474      }475    )cpp",476      R"cpp(477      template$Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]478      class $Class_def[[A]] {479        using $TemplateParameter_decl[[TemplateParam1]] = $TemplateParameter[[T]];480        typedef $TemplateParameter[[T]] $TemplateParameter_decl[[TemplateParam2]];481        using $Primitive_decl[[IntType]] = int;482 483        using $Typedef_decl[[Pointer]] = $TemplateParameter[[T]] *;484        using $Typedef_decl[[LVReference]] = $TemplateParameter[[T]] &;485        using $Typedef_decl[[RVReference]] = $TemplateParameter[[T]]&&;486        using $Typedef_decl[[Array]] = $TemplateParameter[[T]]*[3];487        using $Typedef_decl[[MemberPointer]] = int ($Class[[A]]::*)(int);488 489        // Use various previously defined typedefs in a function type.490        void $Method_decl[[func]](491          $Typedef[[Pointer]], $Typedef[[LVReference]], $Typedef[[RVReference]],492          $Typedef[[Array]], $Typedef[[MemberPointer]]);493      };494    )cpp",495      R"cpp(496      template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]497      void $Function_decl[[phase1]]($TemplateParameter[[T]]);498      template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]499      void $Function_def[[foo]]($TemplateParameter[[T]] $Parameter_def[[P]]) {500        $Function[[phase1]]($Parameter[[P]]);501        $Unknown_dependentName[[phase2]]($Parameter[[P]]);502      }503    )cpp",504      R"cpp(505      class $Class_def[[A]] {506        template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]507        void $Method_decl[[bar]]($TemplateParameter[[T]]);508      };509 510      template $Bracket[[<]]class $TemplateParameter_def[[U]]$Bracket[[>]]511      void $Function_def[[foo]]($TemplateParameter[[U]] $Parameter_def[[P]]) {512        $Class[[A]]().$Method[[bar]]($Parameter[[P]]);513      }514    )cpp",515      R"cpp(516      struct $Class_def[[A]] {517        template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]518        static void $StaticMethod_decl_static[[foo]]($TemplateParameter[[T]]);519      };520 521      template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]522      struct $Class_def[[B]] {523        void $Method_def[[bar]]() {524          $Class[[A]]::$StaticMethod_static[[foo]]($TemplateParameter[[T]]());525        }526      };527    )cpp",528      R"cpp(529      template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]530      void $Function_decl[[foo]](typename $TemplateParameter[[T]]::$Type_dependentName[[Type]]531                                            = $TemplateParameter[[T]]::$Unknown_dependentName[[val]]);532    )cpp",533      R"cpp(534      template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]535      void $Function_def[[foo]]($TemplateParameter[[T]] $Parameter_def[[P]]) {536        $Parameter[[P]].$Unknown_dependentName[[Field]];537      }538    )cpp",539      R"cpp(540      template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]541      class $Class_def[[A]] {542        int $Method_def[[foo]]() {543          return $TemplateParameter[[T]]::$Unknown_dependentName[[Field]];544        }545      };546    )cpp",547      // Highlighting the using decl as the underlying using shadow decl.548      R"cpp(549      void $Function_decl[[foo]]();550      using ::$Function[[foo]];551    )cpp",552      // Highlighting of template template arguments.553      R"cpp(554      template $Bracket[[<]]template $Bracket[[<]]class$Bracket[[>]] class $TemplateParameter_def[[TT]],555                template $Bracket[[<]]class$Bracket[[>]] class ...$TemplateParameter_def[[TTs]]$Bracket[[>]]556      struct $Class_def[[Foo]] {557        $Class[[Foo]]$Bracket[[<]]$TemplateParameter[[TT]], $TemplateParameter[[TTs]]...$Bracket[[>]]558          *$Field_decl[[t]];559      };560    )cpp",561      // Inactive code highlighting562      R"cpp(563      // Code in the preamble.564      // Inactive lines get an empty InactiveCode token at the beginning.565      #ifdef $Macro[[test]]566$InactiveCode[[int Inactive1;]]567      #endif568 569      // A declaration to cause the preamble to end.570      int $Variable_def[[EndPreamble]];571 572      // Code after the preamble.573      // Code inside inactive blocks does not get regular highlightings574      // because it's not part of the AST.575      #define $Macro_decl[[test2]]576      #if defined($Macro[[test]])577$InactiveCode[[int Inactive2;]]578      #elif defined($Macro[[test2]])579      int $Variable_def[[Active1]];580      #else581$InactiveCode[[int Inactive3;]]582      #endif583 584      #ifndef $Macro[[test]]585      int $Variable_def[[Active2]];586      #endif587 588      #ifdef $Macro[[test]]589$InactiveCode[[int Inactive4;]]590      #else591      int $Variable_def[[Active3]];592      #endif593    )cpp",594      // Argument to 'sizeof...'595      R"cpp(596      template $Bracket[[<]]typename... $TemplateParameter_def[[Elements]]$Bracket[[>]]597      struct $Class_def[[TupleSize]] {598        static const int $StaticField_decl_readonly_static[[size]] =599sizeof...($TemplateParameter[[Elements]]);600      };601    )cpp",602      // More dependent types603      R"cpp(604      template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]605      struct $Class_def[[Waldo]] {606        using $Typedef_decl[[Location1]] = typename $TemplateParameter[[T]]607            ::$Type_dependentName[[Resolver]]::$Type_dependentName[[Location]];608        using $Typedef_decl[[Location2]] = typename $TemplateParameter[[T]]609            ::template $Type_dependentName[[Resolver]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]610            ::$Type_dependentName[[Location]];611        using $Typedef_decl[[Location3]] = typename $TemplateParameter[[T]]612            ::$Type_dependentName[[Resolver]]613            ::template $Type_dependentName[[Location]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]];614        static const int $StaticField_decl_readonly_static[[Value]] = $TemplateParameter[[T]]615            ::$Type_dependentName[[Resolver]]::$Unknown_dependentName[[Value]];616      };617    )cpp",618      // Dependent name with heuristic target619      R"cpp(620      template $Bracket[[<]]typename$Bracket[[>]]621      struct $Class_def[[Foo]] {622        int $Field_decl[[Waldo]];623        void $Method_def[[bar]]() {624          $Class[[Foo]]().$Field[[Waldo]];625        }626        template $Bracket[[<]]typename $TemplateParameter_def[[U]]$Bracket[[>]]627        void $Method_def[[bar1]]() {628          $Class[[Foo]]$Bracket[[<]]$TemplateParameter[[U]]$Bracket[[>]]().$Field_dependentName[[Waldo]];629        }630 631        void $Method_decl[[Overload]]();632        void $Method_decl_readonly[[Overload]]() const;633      };634      template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]635      void $Function_def[[baz]]($Class[[Foo]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] $Parameter_def[[o]]) {636        $Parameter[[o]].$Method_readonly_dependentName[[Overload]]();637      }638    )cpp",639      // Concepts640      R"cpp(641      template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]642      concept $Concept_decl[[Fooable]] =643          requires($TemplateParameter[[T]] $Parameter_def[[F]]) {644            $Parameter[[F]].$Unknown_dependentName[[foo]]();645          };646      template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]647          requires $Concept[[Fooable]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]648      void $Function_def[[bar]]($TemplateParameter[[T]] $Parameter_def[[F]]) {649        $Parameter[[F]].$Unknown_dependentName[[foo]]();650      }651 652      struct $Class_def[[F]] {653        void $Method_def[[foo]]() {};654      };655      $Concept[[Fooable]] $Class_deduced[[auto]] $Variable_def[[f]] = $Class[[F]]();656 657      void $Function_def[[Bar]]($Concept[[Fooable]] $TemplateParameter[[auto]] $Parameter_def[[x]]) {}658 659      template$Bracket[[<]]$Concept[[Fooable]] auto $TemplateParameter_def_readonly[[x]]$Bracket[[>]] void $Function_def[[Boo]]() {}660      bool $Variable_def[[b]] = $Concept[[Fooable]]$Bracket[[<]]int$Bracket[[>]];661    )cpp",662      // Dependent template name663      R"cpp(664      template $Bracket[[<]]template $Bracket[[<]]typename$Bracket[[>]] class$Bracket[[>]] struct $Class_def[[A]] {};665      template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]666      using $Typedef_decl[[W]] = $Class[[A]]$Bracket[[<]]667        $TemplateParameter[[T]]::template $Class_dependentName[[Waldo]]668      $Bracket[[>]];669    )cpp",670      R"cpp(671      class $Class_def_abstract[[Abstract]] {672      public:673        virtual void $Method_decl_abstract_virtual[[pure]]() = 0;674        virtual void $Method_decl_virtual[[impl]]();675      };676      void $Function_def[[foo]]($Class_abstract[[Abstract]]* $Parameter_def[[A]]) {677          $Parameter[[A]]->$Method_abstract_virtual[[pure]]();678          $Parameter[[A]]->$Method_virtual[[impl]]();679      }680      )cpp",681      R"cpp(682      <:[deprecated]:> int $Variable_def_deprecated[[x]];683      )cpp",684      R"cpp(685        // ObjC: Classes and methods686        @class $Class_decl[[Forward]];687 688        @interface $Class_def[[Foo]]689        @end690        @interface $Class_def[[Bar]] : $Class[[Foo]]691        -(id) $Method_decl[[x]]:(int)$Parameter_def[[a]] $Method_decl[[y]]:(int)$Parameter_def[[b]];692        +(instancetype)$StaticMethod_decl_static[[sharedInstance]];693        +(void) $StaticMethod_decl_static[[explode]];694        @end695        @implementation $Class_def[[Bar]]696        -(id) $Method_def[[x]]:(int)$Parameter_def[[a]] $Method_def[[y]]:(int)$Parameter_def[[b]] {697          return self;698        }699        +(instancetype)$StaticMethod_def_static[[sharedInstance]] { return 0; }700        +(void) $StaticMethod_def_static[[explode]] {}701        @end702 703        void $Function_def[[m]]($Class[[Bar]] *$Parameter_def[[b]]) {704          [$Parameter[[b]] $Method[[x]]:1 $Method[[y]]:2];705          [$Class[[Bar]] $StaticMethod_static[[explode]]];706        }707      )cpp",708      R"cpp(709        // ObjC: Protocols710        @protocol $Interface_def[[Protocol]]711        @end712        @protocol $Interface_def[[Protocol2]] <$Interface[[Protocol]]>713        @end714        @interface $Class_def[[Klass]] <$Interface[[Protocol]]>715        @end716        id<$Interface[[Protocol]]> $Variable_def[[x]];717      )cpp",718      R"cpp(719        // ObjC: Categories720        @interface $Class_def[[Foo]]721        @end722        @interface $Class[[Foo]]($Namespace_def[[Bar]])723        @end724        @implementation $Class[[Foo]]($Namespace_def[[Bar]])725        @end726      )cpp",727      R"cpp(728        // ObjC: Properties and Ivars.729        @interface $Class_def[[Foo]] {730          int $Field_decl[[_someProperty]];731        }732        @property(nonatomic, assign) int $Field_decl[[someProperty]];733        @property(readonly, class) $Class[[Foo]] *$Field_decl_readonly_static[[sharedInstance]];734        @end735        @implementation $Class_def[[Foo]]736        @synthesize someProperty = _someProperty;737        - (int)$Method_def[[otherMethod]] {738          return 0;739        }740        - (int)$Method_def[[doSomething]] {741          $Class[[Foo]].$Field_static[[sharedInstance]].$Field[[someProperty]] $Operator[[=]] 1;742          self.$Field[[someProperty]] $Operator[[=]] self.$Field[[someProperty]] $Operator[[+]] self.$Field[[otherMethod]] $Operator[[+]] 1;743          self->$Field[[_someProperty]] $Operator[[=]] $Field[[_someProperty]] $Operator[[+]] 1;744          return 0;745        }746        @end747      )cpp",748      // Member imported from dependent base749      R"cpp(750        template $Bracket[[<]]typename$Bracket[[>]] struct $Class_def[[Base]] {751          int $Field_decl[[member]];752        };753        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]754        struct $Class_def[[Derived]] : $Class[[Base]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] {755          using $Class[[Base]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]::$Field_dependentName[[member]];756 757          void $Method_def[[method]]() {758            (void)$Field_dependentName[[member]];759          }760        };761      )cpp",762      // Modifier for variables passed as non-const references763      R"cpp(764        struct $Class_def[[ClassWithOp]] {765            void operator$Operator_decl[[(]]$Operator_decl[[)]](int);766            void operator$Operator_decl[[(]]$Operator_decl[[)]](int, int &);767            void operator$Operator_decl[[(]]$Operator_decl[[)]](int, int, const int &);768            int &operator$Operator_decl[[[]]$Operator_decl[[]]](int &);769            int operator$Operator_decl[[[]]$Operator_decl[[]]](int) const;770        };771        struct $Class_def[[ClassWithStaticMember]] {772            static inline int $StaticField_def_static[[j]] = 0;773        };774        struct $Class_def[[ClassWithRefMembers]] {775          $Class_def_constrDestr[[ClassWithRefMembers]](int $Parameter_def[[i]])776            : $Field[[i1]]($Parameter[[i]]),777              $Field_readonly[[i2]]($Parameter[[i]]),778              $Field[[i3]]($Parameter_usedAsMutableReference[[i]]),779              $Field_readonly[[i4]]($Class[[ClassWithStaticMember]]::$StaticField_static[[j]]),780              $Field[[i5]]($Class[[ClassWithStaticMember]]::$StaticField_static_usedAsMutableReference[[j]])781          {}782          int $Field_decl[[i1]];783          const int &$Field_decl_readonly[[i2]];784          int &$Field_decl[[i3]];785          const int &$Field_decl_readonly[[i4]];786          int &$Field_decl[[i5]];787        };788        void $Function_def[[fun]](int, const int,789                                   int*, const int*,790                                   int&, const int&,791                                   int*&, const int*&, const int* const &,792                                   int**, int**&, int** const &,793                                   int = 123) {794          int $LocalVariable_def[[val]];795          int* $LocalVariable_def[[ptr]];796          const int* $LocalVariable_def_readonly[[constPtr]];797          int** $LocalVariable_def[[array]];798          $Function[[fun]]($LocalVariable[[val]], $LocalVariable[[val]],799                           $LocalVariable_usedAsMutablePointer[[ptr]], $LocalVariable_readonly[[constPtr]],800                           $LocalVariable_usedAsMutableReference[[val]], $LocalVariable[[val]],801 802                           $LocalVariable_usedAsMutableReference[[ptr]],803                           $LocalVariable_readonly_usedAsMutableReference[[constPtr]],804                           $LocalVariable_readonly[[constPtr]],805 806                           $LocalVariable_usedAsMutablePointer[[array]], $LocalVariable_usedAsMutableReference[[array]],807                           $LocalVariable[[array]]808                           );809          [](int){}$Operator_userDefined[[(]]$LocalVariable[[val]]$Operator_userDefined[[)]];810          [](int&){}$Operator_userDefined[[(]]$LocalVariable_usedAsMutableReference[[val]]$Operator_userDefined[[)]];811          [](const int&){}$Operator_userDefined[[(]]$LocalVariable[[val]]$Operator_userDefined[[)]];812          $Class[[ClassWithOp]] $LocalVariable_def[[c]];813          const $Class[[ClassWithOp]] $LocalVariable_def_readonly[[c2]];814          $LocalVariable[[c]]$Operator_userDefined[[(]]$LocalVariable[[val]]$Operator_userDefined[[)]];815          $LocalVariable[[c]]$Operator_userDefined[[(]]0, $LocalVariable_usedAsMutableReference[[val]]$Operator_userDefined[[)]];816          $LocalVariable[[c]]$Operator_userDefined[[(]]0, 0, $LocalVariable[[val]]$Operator_userDefined[[)]];817          $LocalVariable[[c]]$Operator_userDefined[[[]]$LocalVariable_usedAsMutableReference[[val]]$Operator_userDefined[[]]];818          $LocalVariable_readonly[[c2]]$Operator_userDefined[[[]]$LocalVariable[[val]]$Operator_userDefined[[]]];819        }820        struct $Class_def[[S]] {821          $Class_def_constrDestr[[S]](int&) {822            $Class[[S]] $LocalVariable_def[[s1]]($Field_usedAsMutableReference[[field]]);823            $Class[[S]] $LocalVariable_def[[s2]]($LocalVariable[[s1]].$Field_usedAsMutableReference[[field]]);824 825            $Class[[S]] $LocalVariable_def[[s3]]($StaticField_static_usedAsMutableReference[[staticField]]);826            $Class[[S]] $LocalVariable_def[[s4]]($Class[[S]]::$StaticField_static_usedAsMutableReference[[staticField]]);827          }828          int $Field_decl[[field]];829          static int $StaticField_decl_static[[staticField]];830        };831        template $Bracket[[<]]typename $TemplateParameter_def[[X]]$Bracket[[>]]832        void $Function_def[[foo]]($TemplateParameter[[X]]& $Parameter_def[[x]]) {833          // We do not support dependent types, so this one should *not* get the modifier.834          $Function[[foo]]($Parameter[[x]]);835        }836      )cpp",837      // init-captures838      R"cpp(839        void $Function_def[[foo]]() {840          int $LocalVariable_def[[a]], $LocalVariable_def[[b]];841          [ $LocalVariable_def[[c]] = $LocalVariable[[a]],842            $LocalVariable_def[[d]]($LocalVariable[[b]]) ]() {}$Operator_userDefined[[(]]$Operator_userDefined[[)]];843        }844      )cpp",845      // Enum base specifier846      R"cpp(847        using $Primitive_decl[[MyTypedef]] = int;848        enum $Enum_decl[[MyEnum]] : $Primitive[[MyTypedef]] {};849      )cpp",850      // Enum base specifier851      R"cpp(852        typedef int $Primitive_decl[[MyTypedef]];853        enum $Enum_decl[[MyEnum]] : $Primitive[[MyTypedef]] {};854      )cpp",855      // Using enum856      R"cpp(857      enum class $Enum_decl[[Color]] { $EnumConstant_decl_readonly[[Black]] };858      namespace $Namespace_decl[[ns]] {859        using enum $Enum[[Color]];860        $Enum[[Color]] $Variable_def[[ModelT]] = $EnumConstant[[Black]];861      }862      )cpp",863      // Issue 1096864      R"cpp(865        void $Function_decl[[Foo]]();866        // Use <: :> digraphs for deprecated attribute to avoid conflict with annotation syntax867        <:<:deprecated:>:> void $Function_decl_deprecated[[Foo]](int* $Parameter_def[[x]]);868        void $Function_decl[[Foo]](int $Parameter_def[[x]]);869        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]870        void $Function_def[[Bar]]($TemplateParameter[[T]] $Parameter_def[[x]]) {871            $Function_deprecated[[Foo]]($Parameter[[x]]);872            $Function_deprecated[[Foo]]($Parameter[[x]]);873            $Function_deprecated[[Foo]]($Parameter[[x]]);874        }875      )cpp",876      // Predefined identifiers877      R"cpp(878        void $Function_def[[Foo]]() {879            const char *$LocalVariable_def_readonly[[s]] = $LocalVariable_readonly_static[[__func__]];880        }881      )cpp",882      // override and final883      R"cpp(884        class $Class_def_abstract[[Base]] { virtual void $Method_decl_abstract_virtual[[m]]() = 0; };885        class $Class_def[[override]] : public $Class_abstract[[Base]] { void $Method_decl_virtual[[m]]() $Modifier[[override]]; };886        class $Class_def[[final]] : public $Class[[override]] { void $Method_decl_virtual[[m]]() $Modifier[[override]] $Modifier[[final]]; };887      )cpp",888      // Issue 1222: readonly modifier for generic parameter889      R"cpp(890        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]891        auto $Function_def[[foo]](const $TemplateParameter[[T]] $Parameter_def_readonly[[template_type]],892                                  const $TemplateParameter[[auto]] $Parameter_def_readonly[[auto_type]],893                                  const int $Parameter_def_readonly[[explicit_type]]) {894            return $Parameter_readonly[[template_type]]895                 $Operator_userDefined[[+]] $Parameter_readonly[[auto_type]]896                 $Operator_userDefined[[+]] $Parameter_readonly[[explicit_type]];897        }898      )cpp",899      // Explicit template specialization900      R"cpp(901        struct $Class_def[[Base]]{};902        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]903        struct $Class_def[[S]] : public $Class[[Base]] {};904        template $Bracket[[<]]$Bracket[[>]]905        struct $Class_def[[S]]$Bracket[[<]]void$Bracket[[>]] : public $Class[[Base]] {};906 907        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]908        $TemplateParameter[[T]] $Variable_def[[x]] = {};909        template $Bracket[[<]]$Bracket[[>]]910        int $Variable_def[[x]]$Bracket[[<]]int$Bracket[[>]] = (int)sizeof($Class[[Base]]);911      )cpp",912      // operator calls in template913      R"cpp(914        template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] class $Class_def[[C]] {915            bool $Method_def[[compare]]($TemplateParameter[[T]] $Parameter_def[[t1]], $TemplateParameter[[T]] $Parameter_def[[t2]]) { return $Parameter[[t1]] $Operator_userDefined[[==]] $Parameter[[t2]]; }916            $TemplateParameter[[T]] $Method_def[[deref]]($TemplateParameter[[T]] *$Parameter_def[[t]]) { return $Operator_userDefined[[*]]$Parameter[[t]]; }917        };918      )cpp",919      // new and delete920      R"cpp(921        struct $Class_def[[S]] { int *$Field_decl[[a]]; };922        void $Function_def[[f]]() {923          $Class[[S]] *$LocalVariable_def[[s]] = $Operator[[new]] $Class[[S]];924          $LocalVariable[[s]]->$Field[[a]] $Operator[[=]] $Operator[[new]] int[10];925          $Operator[[delete]][] $LocalVariable[[s]]->$Field[[a]];926          $Operator[[delete]] $LocalVariable[[s]];927        }928      )cpp",929      // explicit operator invocation930      R"cpp(931        struct $Class_def[[S]] {932            $Class[[S]] operator$Operator_decl[[+]](const $Class[[S]] &$Parameter_def_readonly[[other]]);933        };934        void $Function_def[[f]]() {935            $Class[[S]] $LocalVariable_def[[s]];936            $Class[[S]] $LocalVariable_def[[s2]] = $LocalVariable[[s]].operator$Operator_userDefined[[+]]($LocalVariable[[s]]);937        }938      )cpp",939      R"cpp(940        // Brackets support: C++ casts941        void $Function_def[[f]]() {942          struct $Class_def[[B]] { virtual ~$Class_decl_constrDestr[[B]](); };943          struct $Class_def[[D]] : public $Class[[B]] {};944          $Class[[B]] $LocalVariable_def[[b]];945          int $LocalVariable_def[[i]] = static_cast$Bracket[[<]]int$Bracket[[>]](3.5);946          void *$LocalVariable_def[[p]] = reinterpret_cast$Bracket[[<]]void *$Bracket[[>]](0);947          $Class[[D]] &$LocalVariable_def[[d]] = dynamic_cast$Bracket[[<]]$Class[[D]] &$Bracket[[>]]($LocalVariable[[b]]);948        }949      )cpp",950      // Brackets support: Nested template instantiations.951      R"cpp(952        template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] struct $Class_def[[S]] {};953        void $Function_def[[f]]() {954            $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]$Bracket[[>]] $LocalVariable_def[[s1]];955            $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]\956$Bracket[[>]] $LocalVariable_def[[s2]];957            $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]$Bracket[[>]]$Bracket[[>]] $LocalVariable_def[[s3]];958            $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]\959$Bracket[[>]]$Bracket[[>]] $LocalVariable_def[[s4]];960            $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]\961  $Bracket[[>]]$Bracket[[>]] $LocalVariable_def[[s5]];962            $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]\963$Bracket[[>]]$Bracket[[>]] $LocalVariable_def[[s6]];964            $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]$Bracket[[>]]\965  $Bracket[[>]] $LocalVariable_def[[s7]];966      }967      )cpp",968      // Brackets support: One of the brackets is a macro.969      R"cpp(970        #define $Macro_decl[[LESS]] <971        template $Macro[[LESS]] typename $TemplateParameter_def[[T]] > class $Class_def[[A]] {};972      )cpp",973      // Brackets support: Specializations974      R"cpp(975        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] class $Class_def[[S]] {976        public:977          template $Bracket[[<]]typename $TemplateParameter_def[[U]]$Bracket[[>]] class $Class_decl[[Nested]];978        };979        template $Bracket[[<]]$Bracket[[>]] class $Class_def[[S]]$Bracket[[<]]int$Bracket[[>]] {};980        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]981        class $Class_def[[S]]$Bracket[[<]]$TemplateParameter[[T]]*$Bracket[[>]] {};982        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]983        template $Bracket[[<]]typename $TemplateParameter_def[[U]]$Bracket[[>]]984        class $Class[[S]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]::$Class_def[[Nested]] {};985        template $Bracket[[<]]$Bracket[[>]]986        template $Bracket[[<]]$Bracket[[>]]987        class $Class[[S]]$Bracket[[<]]float$Bracket[[>]]::$Class_def[[Nested]]$Bracket[[<]]float$Bracket[[>]] {};988        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] void $Function_decl[[foo]]();989        void $Function_def[[bar]]() {990          $Function[[foo]]$Bracket[[<]]int$Bracket[[>]]();991        }992        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] constexpr int $Variable_def_readonly[[V]] = 42;993        constexpr int $Variable_def_readonly[[Y]] = $Variable_readonly[[V]]$Bracket[[<]]char$Bracket[[>]];994        template $Bracket[[<]]$Bracket[[>]]995        constexpr int $Variable_def_readonly[[V]]$Bracket[[<]]int$Bracket[[>]] = 5;996        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]997        constexpr int $Variable_def_readonly[[V]]$Bracket[[<]]$TemplateParameter[[T]]*$Bracket[[>]] = 6;998        template $Bracket[[<]]typename$Bracket[[>]]999        class $Class_def[[A]] {1000          enum class $Enum_decl[[E]];1001        };1002        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]1003        enum class $Class[[A]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]::$Enum_decl[[E]] {$EnumConstant_decl_readonly[[X]], $EnumConstant_decl_readonly[[Y]], $EnumConstant_decl_readonly[[Z]]};1004        template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]]1005        class $Class_def[[B]] {1006          template $Bracket[[<]]class $TemplateParameter_def[[U]]$Bracket[[>]] void $Method_def[[foo]]($TemplateParameter[[U]]) { }1007          template$Bracket[[<]]$Bracket[[>]] void $Method_def[[foo]]$Bracket[[<]]int$Bracket[[>]](int) { }1008          friend void $Function_decl[[foo]]$Bracket[[<]]$Bracket[[>]]($TemplateParameter[[T]]);1009        };1010      )cpp",1011      // Brackets support: Function calls1012      R"cpp(1013        template $Bracket[[<]]typename$Bracket[[>]] void $Function_decl[[free]]();1014        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]1015          struct $Class_def[[A]] {1016            template $Bracket[[<]]typename$Bracket[[>]] void $Method_decl[[mem]]();1017        };1018        void $Function_def[[foo]]() {1019          $Class[[A]]$Bracket[[<]]int$Bracket[[>]] $LocalVariable_def[[a]];1020          $LocalVariable[[a]].$Method[[mem]]$Bracket[[<]]int$Bracket[[>]]();1021        }1022        template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]1023        void $Function_def[[bar]]() {1024          $Function[[free]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]();1025          $Class[[A]]$Bracket[[<]]int$Bracket[[>]] $LocalVariable_def[[a]];1026          $LocalVariable[[a]].$Method[[mem]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]();1027          $Class[[A]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] $LocalVariable_def[[b]];1028          $LocalVariable[[b]].template $Method_dependentName[[mem]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]();1029        }1030      )cpp",1031      // Brackets support: Concepts1032      R"cpp(1033        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]1034        concept $Concept_decl[[C]] = true;1035        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] requires $Concept[[C]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]1036        class $Class_def[[Z]] {};1037        template $Bracket[[<]]typename, typename$Bracket[[>]]1038        concept $Concept_decl[[C2]] = true;1039        template $Bracket[[<]]$Concept[[C2]]$Bracket[[<]]int$Bracket[[>]] $TemplateParameter_def[[A]]$Bracket[[>]]1040        class $Class_def[[B]] {};1041      )cpp",1042      // Labels1043      R"cpp(1044        bool $Function_def[[funcWithGoto]](bool $Parameter_def[[b]]) {1045          if ($Parameter[[b]])1046            goto $Label[[return_true]];1047          return false;1048          $Label_decl[[return_true]]:1049            return true;1050        }1051      )cpp",1052      // no crash1053      R"cpp(1054        struct $Class_def[[Foo]] {1055          void $Method_decl[[foo]]();1056        };1057 1058        void $Function_def[[s]]($Class[[Foo]] $Parameter_def[[f]]) {1059          auto $LocalVariable_def[[k]] = $Operator[[&]]$Class[[Foo]]::$Method[[foo]];1060          ($Parameter[[f]]$Operator[[.*]]$LocalVariable[[k]])(); // no crash on VisitCXXMemberCallExpr1061        }1062      )cpp",1063      R"cpp(1064        template$Bracket[[<]]typename$Bracket[[>]]1065        class $Class_def[[Foo]] {};1066 1067        template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]1068        void $Function_def[[k]]() {1069          auto $LocalVariable_def[[s]] = $Operator[[new]] $Class[[Foo]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]();1070          $Operator[[delete]] $LocalVariable[[s]];1071        }1072      )cpp",1073      // Recursive UsingValueDecl1074      R"cpp(1075        template $Bracket[[<]]int$Bracket[[>]] class $Class_def[[X]] {1076          template $Bracket[[<]]int$Bracket[[>]] class $Class_def[[Y]] {1077            using $Class[[Y]]$Bracket[[<]]0$Bracket[[>]]::$Unknown_dependentName[[xxx]];1078          };1079        };1080    )cpp",1081      // Heuristically resolved IndirectFieldDecl1082      R"cpp(1083        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]1084        struct $Class_def[[Base]] {1085          struct {1086            int $Field_decl[[waldo]];1087          };1088        };1089        template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]]1090        struct $Class_def[[Derived]] : $Class[[Base]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] {1091          using $Class[[Base]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]::$Field_dependentName[[waldo]];1092          void $Method_def[[foo]]() {1093            $Field_dependentName[[waldo]];1094          }1095        };1096    )cpp",1097      // Pointer-to-member with nested-name-specifiers1098      R"cpp(1099      struct $Class_def[[Outer]] {1100        struct $Class_def[[Inner]] {};1101      };1102      using $Typedef_decl[[Alias]] = void ($Class[[Outer]]::$Class[[Inner]]:: *)();1103    )cpp"};1104  for (const auto &TestCase : TestCases)1105    // Mask off scope modifiers to keep the tests manageable.1106    // They're tested separately.1107    checkHighlightings(TestCase, {}, ~ScopeModifierMask);1108 1109  checkHighlightings(R"cpp(1110    class $Class_def[[A]] {1111      #include "imp.h"1112    };1113  )cpp",1114                     {{"imp.h", R"cpp(1115    int someMethod();1116    void otherMethod();1117  )cpp"}},1118                     ~ScopeModifierMask);1119 1120  // A separate test for macros in headers.1121  checkHighlightings(R"cpp(1122    #include "imp.h"1123    $Macro[[DEFINE_Y]]1124    $Macro[[DXYZ_Y]](A);1125  )cpp",1126                     {{"imp.h", R"cpp(1127    #define DXYZ(X) class X {};1128    #define DXYZ_Y(Y) DXYZ(x##Y)1129    #define DEFINE(X) int X;1130    #define DEFINE_Y DEFINE(Y)1131  )cpp"}},1132                     ~ScopeModifierMask);1133 1134  checkHighlightings(R"cpp(1135    #include "SYSObject.h"1136    @interface $Class_defaultLibrary[[SYSObject]] ($Namespace_def[[UserCategory]])1137    @property(nonatomic, readonly) int $Field_decl_readonly[[user_property]];1138    @end1139    int $Function_def[[somethingUsingSystemSymbols]]() {1140      $Class_defaultLibrary[[SYSObject]] *$LocalVariable_def[[obj]] = [$Class_defaultLibrary[[SYSObject]] $StaticMethod_static_defaultLibrary[[new]]];1141      return $LocalVariable[[obj]].$Field_defaultLibrary[[value]] $Operator[[+]] $LocalVariable[[obj]].$Field_readonly[[user_property]];1142    }1143  )cpp",1144                     {{"SystemSDK/SYSObject.h", R"cpp(1145    @interface SYSObject1146    @property(nonatomic, assign) int value;1147    + (instancetype)new;1148    @end1149  )cpp"}},1150                     ~ScopeModifierMask, {"-isystemSystemSDK/"});1151}1152 1153TEST(SemanticHighlighting, ScopeModifiers) {1154  const char *TestCases[] = {1155      R"cpp(1156        static int $Variable_fileScope[[x]];1157        namespace $Namespace_globalScope[[ns]] {1158          class $Class_globalScope[[x]];1159        }1160        namespace {1161          void $Function_fileScope[[foo]]();1162        }1163      )cpp",1164      R"cpp(1165        void $Function_globalScope[[foo]](int $Parameter_functionScope[[y]]) {1166          int $LocalVariable_functionScope[[z]];1167        }1168      )cpp",1169      R"cpp(1170        // Lambdas are considered functions, not classes.1171        auto $Variable_fileScope[[x]] = [$LocalVariable_functionScope[[m]](42)] {1172          return $LocalVariable_functionScope[[m]];1173        };1174      )cpp",1175      R"cpp(1176        // Classes in functions are classes.1177        void $Function_globalScope[[foo]]() {1178          class $Class_functionScope[[X]] {1179            int $Field_classScope[[x]];1180          };1181        };1182      )cpp",1183      R"cpp(1184        template $Bracket[[<]]int $TemplateParameter_classScope[[T]]$Bracket[[>]]1185        class $Class_globalScope[[X]] {1186        };1187      )cpp",1188      R"cpp(1189        // No useful scope for template parameters of variable templates.1190        template $Bracket[[<]]typename $TemplateParameter[[A]]$Bracket[[>]]1191        unsigned $Variable_globalScope[[X]] =1192          $TemplateParameter[[A]]::$Unknown_classScope[[x]];1193      )cpp",1194      R"cpp(1195        #define $Macro_globalScope[[X]] 11196        int $Variable_globalScope[[Y]] = $Macro_globalScope[[X]];1197      )cpp",1198  };1199 1200  for (const char *Test : TestCases)1201    checkHighlightings(Test, {}, ScopeModifierMask);1202}1203 1204// Ranges are highlighted as variables, unless highlighted as $Function etc.1205std::vector<HighlightingToken> tokens(llvm::StringRef MarkedText) {1206  Annotations A(MarkedText);1207  std::vector<HighlightingToken> Results;1208  for (const Range& R : A.ranges())1209    Results.push_back({HighlightingKind::Variable, 0, R});1210  for (unsigned I = 0; I < static_cast<unsigned>(HighlightingKind::LastKind); ++I) {1211    HighlightingKind Kind = static_cast<HighlightingKind>(I);1212    for (const Range& R : A.ranges(llvm::to_string(Kind)))1213      Results.push_back({Kind, 0, R});1214  }1215  llvm::sort(Results);1216  return Results;1217}1218 1219TEST(SemanticHighlighting, toSemanticTokens) {1220  auto Tokens = tokens(R"(1221 [[blah]]1222 1223    $Function[[big]] [[bang]]1224  )");1225  Tokens.front().Modifiers |= unsigned(HighlightingModifier::Declaration);1226  Tokens.front().Modifiers |= unsigned(HighlightingModifier::Readonly);1227  auto Results = toSemanticTokens(Tokens, /*Code=*/"");1228 1229  ASSERT_THAT(Results, SizeIs(3));1230  EXPECT_EQ(Results[0].tokenType, unsigned(HighlightingKind::Variable));1231  EXPECT_EQ(Results[0].tokenModifiers,1232            unsigned(HighlightingModifier::Declaration) |1233                unsigned(HighlightingModifier::Readonly));1234  EXPECT_EQ(Results[0].deltaLine, 1u);1235  EXPECT_EQ(Results[0].deltaStart, 1u);1236  EXPECT_EQ(Results[0].length, 4u);1237 1238  EXPECT_EQ(Results[1].tokenType, unsigned(HighlightingKind::Function));1239  EXPECT_EQ(Results[1].tokenModifiers, 0u);1240  EXPECT_EQ(Results[1].deltaLine, 2u);1241  EXPECT_EQ(Results[1].deltaStart, 4u);1242  EXPECT_EQ(Results[1].length, 3u);1243 1244  EXPECT_EQ(Results[2].tokenType, unsigned(HighlightingKind::Variable));1245  EXPECT_EQ(Results[1].tokenModifiers, 0u);1246  EXPECT_EQ(Results[2].deltaLine, 0u);1247  EXPECT_EQ(Results[2].deltaStart, 4u);1248  EXPECT_EQ(Results[2].length, 4u);1249}1250 1251TEST(SemanticHighlighting, diffSemanticTokens) {1252  auto Before = toSemanticTokens(tokens(R"(1253    [[foo]] [[bar]] [[baz]]1254    [[one]] [[two]] [[three]]1255  )"),1256                                 /*Code=*/"");1257  EXPECT_THAT(diffTokens(Before, Before), IsEmpty());1258 1259  auto After = toSemanticTokens(tokens(R"(1260    [[foo]] [[hello]] [[world]] [[baz]]1261    [[one]] [[two]] [[three]]1262  )"),1263                                /*Code=*/"");1264 1265  // Replace [bar, baz] with [hello, world, baz]1266  auto Diff = diffTokens(Before, After);1267  ASSERT_THAT(Diff, SizeIs(1));1268  EXPECT_EQ(1u, Diff.front().startToken);1269  EXPECT_EQ(2u, Diff.front().deleteTokens);1270  ASSERT_THAT(Diff.front().tokens, SizeIs(3));1271  // hello1272  EXPECT_EQ(0u, Diff.front().tokens[0].deltaLine);1273  EXPECT_EQ(4u, Diff.front().tokens[0].deltaStart);1274  EXPECT_EQ(5u, Diff.front().tokens[0].length);1275  // world1276  EXPECT_EQ(0u, Diff.front().tokens[1].deltaLine);1277  EXPECT_EQ(6u, Diff.front().tokens[1].deltaStart);1278  EXPECT_EQ(5u, Diff.front().tokens[1].length);1279  // baz1280  EXPECT_EQ(0u, Diff.front().tokens[2].deltaLine);1281  EXPECT_EQ(6u, Diff.front().tokens[2].deltaStart);1282  EXPECT_EQ(3u, Diff.front().tokens[2].length);1283}1284 1285TEST(SemanticHighlighting, MultilineTokens) {1286  llvm::StringRef AnnotatedCode = R"cpp(1287  [[fo1288o1289o]] [[bar]])cpp";1290  auto Toks = toSemanticTokens(tokens(AnnotatedCode),1291                               Annotations(AnnotatedCode).code());1292  ASSERT_THAT(Toks, SizeIs(4));1293  // foo1294  EXPECT_EQ(Toks[0].deltaLine, 1u);1295  EXPECT_EQ(Toks[0].deltaStart, 2u);1296  EXPECT_EQ(Toks[0].length, 2u);1297  EXPECT_EQ(Toks[1].deltaLine, 1u);1298  EXPECT_EQ(Toks[1].deltaStart, 0u);1299  EXPECT_EQ(Toks[1].length, 1u);1300  EXPECT_EQ(Toks[2].deltaLine, 1u);1301  EXPECT_EQ(Toks[2].deltaStart, 0u);1302  EXPECT_EQ(Toks[2].length, 1u);1303 1304  // bar1305  EXPECT_EQ(Toks[3].deltaLine, 0u);1306  EXPECT_EQ(Toks[3].deltaStart, 2u);1307  EXPECT_EQ(Toks[3].length, 3u);1308}1309 1310TEST(SemanticHighlighting, WithHighlightingFilter) {1311  llvm::StringRef AnnotatedCode = R"cpp(1312int *$Variable[[x]] = new int;1313)cpp";1314  Config Cfg;1315  Cfg.SemanticTokens.DisabledKinds = {"Operator"};1316  Cfg.SemanticTokens.DisabledModifiers = {"Declaration", "Definition"};1317  WithContextValue WithCfg(Config::Key, std::move(Cfg));1318  checkHighlightings(AnnotatedCode, {}, ~ScopeModifierMask);1319}1320} // namespace1321} // namespace clangd1322} // namespace clang1323