185032534SAlex Richardson //===- unittest/Format/TokenAnnotatorTest.cpp - Formatting unit tests -----===// 285032534SAlex Richardson // 385032534SAlex Richardson // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 485032534SAlex Richardson // See https://llvm.org/LICENSE.txt for license information. 585032534SAlex Richardson // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 685032534SAlex Richardson // 785032534SAlex Richardson //===----------------------------------------------------------------------===// 885032534SAlex Richardson 985032534SAlex Richardson #include "clang/Format/Format.h" 1085032534SAlex Richardson 1185032534SAlex Richardson #include "FormatTestUtils.h" 1285032534SAlex Richardson #include "TestLexer.h" 1385032534SAlex Richardson #include "gtest/gtest.h" 1485032534SAlex Richardson 1585032534SAlex Richardson namespace clang { 1685032534SAlex Richardson namespace format { 179aab0db1SBjörn Schäpers 189aab0db1SBjörn Schäpers // Not really the equality, but everything we need. 199aab0db1SBjörn Schäpers static bool operator==(const FormatToken &LHS, 209aab0db1SBjörn Schäpers const FormatToken &RHS) noexcept { 219aab0db1SBjörn Schäpers return LHS.Tok.getKind() == RHS.Tok.getKind() && 229aab0db1SBjörn Schäpers LHS.getType() == RHS.getType(); 239aab0db1SBjörn Schäpers } 249aab0db1SBjörn Schäpers 2585032534SAlex Richardson namespace { 2685032534SAlex Richardson 271c58208dSOwen Pan class TokenAnnotatorTest : public testing::Test { 2885032534SAlex Richardson protected: 291c58208dSOwen Pan TokenList annotate(StringRef Code, 3085032534SAlex Richardson const FormatStyle &Style = getLLVMStyle()) { 3175a1790fSAlex Richardson return TestLexer(Allocator, Buffers, Style).annotate(Code); 3285032534SAlex Richardson } 3375a1790fSAlex Richardson llvm::SpecificBumpPtrAllocator<FormatToken> Allocator; 3475a1790fSAlex Richardson std::vector<std::unique_ptr<llvm::MemoryBuffer>> Buffers; 3585032534SAlex Richardson }; 3685032534SAlex Richardson 3785032534SAlex Richardson #define EXPECT_TOKEN_KIND(FormatTok, Kind) \ 3885032534SAlex Richardson EXPECT_EQ((FormatTok)->Tok.getKind(), Kind) << *(FormatTok) 3985032534SAlex Richardson #define EXPECT_TOKEN_TYPE(FormatTok, Type) \ 4085032534SAlex Richardson EXPECT_EQ((FormatTok)->getType(), Type) << *(FormatTok) 41f93182a8Ssstwcw #define EXPECT_TOKEN_PRECEDENCE(FormatTok, Prec) \ 42f93182a8Ssstwcw EXPECT_EQ((FormatTok)->getPrecedence(), Prec) << *(FormatTok) 43d39929b9SGalen Elias #define EXPECT_BRACE_KIND(FormatTok, Kind) \ 44d39929b9SGalen Elias EXPECT_EQ(FormatTok->getBlockKind(), Kind) << *(FormatTok) 45438ad9f2SOwen Pan #define EXPECT_SPLIT_PENALTY(FormatTok, Penalty) \ 46438ad9f2SOwen Pan EXPECT_EQ(FormatTok->SplitPenalty, Penalty) << *(FormatTok) 4785032534SAlex Richardson #define EXPECT_TOKEN(FormatTok, Kind, Type) \ 4885032534SAlex Richardson do { \ 4985032534SAlex Richardson EXPECT_TOKEN_KIND(FormatTok, Kind); \ 5085032534SAlex Richardson EXPECT_TOKEN_TYPE(FormatTok, Type); \ 511d03548fSBjörn Schäpers } while (false) 5285032534SAlex Richardson 53a74ff3acSBjörn Schäpers TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) { 5485032534SAlex Richardson auto Tokens = annotate("auto x = [](const decltype(x) &ptr) {};"); 5588d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 18u) << Tokens; 5685032534SAlex Richardson EXPECT_TOKEN(Tokens[7], tok::kw_decltype, TT_Unknown); 5785032534SAlex Richardson EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_TypeDeclarationParen); 5885032534SAlex Richardson EXPECT_TOKEN(Tokens[9], tok::identifier, TT_Unknown); 5985032534SAlex Richardson EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_TypeDeclarationParen); 6085032534SAlex Richardson EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference); 61a74ff3acSBjörn Schäpers 6285032534SAlex Richardson Tokens = annotate("auto x = [](const decltype(x) *ptr) {};"); 6388d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 18u) << Tokens; 6485032534SAlex Richardson EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_TypeDeclarationParen); 6585032534SAlex Richardson EXPECT_TOKEN(Tokens[11], tok::star, TT_PointerOrReference); 6685032534SAlex Richardson 6785032534SAlex Richardson Tokens = annotate("#define lambda [](const decltype(x) &ptr) {}"); 6888d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 17u) << Tokens; 6985032534SAlex Richardson EXPECT_TOKEN(Tokens[7], tok::kw_decltype, TT_Unknown); 7085032534SAlex Richardson EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_TypeDeclarationParen); 7185032534SAlex Richardson EXPECT_TOKEN(Tokens[9], tok::identifier, TT_Unknown); 7285032534SAlex Richardson EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_TypeDeclarationParen); 7385032534SAlex Richardson EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference); 74a74ff3acSBjörn Schäpers 7585032534SAlex Richardson Tokens = annotate("#define lambda [](const decltype(x) *ptr) {}"); 7688d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 17u) << Tokens; 7785032534SAlex Richardson EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_TypeDeclarationParen); 7885032534SAlex Richardson EXPECT_TOKEN(Tokens[11], tok::star, TT_PointerOrReference); 791e7cc72aSBjörn Schäpers 801e7cc72aSBjörn Schäpers Tokens = annotate("void f() {\n" 811e7cc72aSBjörn Schäpers " while (p < a && *p == 'a')\n" 821e7cc72aSBjörn Schäpers " p++;\n" 831e7cc72aSBjörn Schäpers "}"); 8488d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 21u) << Tokens; 851e7cc72aSBjörn Schäpers EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_BinaryOperator); 861e7cc72aSBjörn Schäpers EXPECT_TOKEN(Tokens[11], tok::star, TT_UnaryOperator); 87c261f78dSsstwcw 88c261f78dSsstwcw Tokens = annotate("case *x:"); 8988d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 5u) << Tokens; 90c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::star, TT_UnaryOperator); 91c261f78dSsstwcw Tokens = annotate("case &x:"); 9288d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 5u) << Tokens; 93c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::amp, TT_UnaryOperator); 94b646f095SHuang Zhen-Hong 9588934a82SOwen Pan Tokens = annotate("bool b = 3 == int{3} && true;"); 9688d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 13u) << Tokens; 97ef71383bSjackh EXPECT_TOKEN(Tokens[9], tok::ampamp, TT_BinaryOperator); 98ef71383bSjackh 99b646f095SHuang Zhen-Hong Tokens = annotate("struct {\n" 100b646f095SHuang Zhen-Hong "} *ptr;"); 10188d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 7u) << Tokens; 102b646f095SHuang Zhen-Hong EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference); 103b646f095SHuang Zhen-Hong Tokens = annotate("union {\n" 104b646f095SHuang Zhen-Hong "} *ptr;"); 10588d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 7u) << Tokens; 106b646f095SHuang Zhen-Hong EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference); 107b646f095SHuang Zhen-Hong Tokens = annotate("class {\n" 108b646f095SHuang Zhen-Hong "} *ptr;"); 10988d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 7u) << Tokens; 110b646f095SHuang Zhen-Hong EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference); 111b646f095SHuang Zhen-Hong 112b646f095SHuang Zhen-Hong Tokens = annotate("struct {\n" 113b646f095SHuang Zhen-Hong "} &&ptr = {};"); 11488d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 10u) << Tokens; 115b646f095SHuang Zhen-Hong EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference); 116b646f095SHuang Zhen-Hong Tokens = annotate("union {\n" 117b646f095SHuang Zhen-Hong "} &&ptr = {};"); 11888d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 10u) << Tokens; 119b646f095SHuang Zhen-Hong EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference); 120b646f095SHuang Zhen-Hong Tokens = annotate("class {\n" 121b646f095SHuang Zhen-Hong "} &&ptr = {};"); 12288d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 10u) << Tokens; 123b646f095SHuang Zhen-Hong EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference); 1248dd2ef21SKrasimir Georgiev Tokens = annotate("int i = int{42} * 2;"); 12588d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 11u) << Tokens; 1268dd2ef21SKrasimir Georgiev EXPECT_TOKEN(Tokens[7], tok::star, TT_BinaryOperator); 1273bbdf06bSjackh 1283bbdf06bSjackh Tokens = annotate("delete[] *ptr;"); 12988d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 7u) << Tokens; 1303bbdf06bSjackh EXPECT_TOKEN(Tokens[3], tok::star, TT_UnaryOperator); 1313bbdf06bSjackh Tokens = annotate("delete[] **ptr;"); 13288d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 8u) << Tokens; 1333bbdf06bSjackh EXPECT_TOKEN(Tokens[3], tok::star, TT_UnaryOperator); 1343bbdf06bSjackh EXPECT_TOKEN(Tokens[4], tok::star, TT_UnaryOperator); 1353bbdf06bSjackh Tokens = annotate("delete[] *(ptr);"); 13688d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 9u) << Tokens; 1373bbdf06bSjackh EXPECT_TOKEN(Tokens[3], tok::star, TT_UnaryOperator); 13894215d2bSEmilia Dreamer 13994215d2bSEmilia Dreamer Tokens = annotate("void f() { void (*fnptr)(char* foo); }"); 14088d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 18u) << Tokens; 14194215d2bSEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen); 14294215d2bSEmilia Dreamer // FIXME: The star of a function pointer probably makes more sense as 14394215d2bSEmilia Dreamer // TT_PointerOrReference. 14494215d2bSEmilia Dreamer EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator); 14594215d2bSEmilia Dreamer EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference); 14694215d2bSEmilia Dreamer 14794215d2bSEmilia Dreamer Tokens = annotate("void f() { void (*fnptr)(t* foo); }"); 14888d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 18u) << Tokens; 14994215d2bSEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen); 15094215d2bSEmilia Dreamer EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator); 15194215d2bSEmilia Dreamer EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference); 15270de684dSTobias Hieta 153e864ac69SMicah Weston Tokens = annotate("int f3() { return sizeof(Foo&); }"); 154e864ac69SMicah Weston ASSERT_EQ(Tokens.size(), 14u) << Tokens; 155e864ac69SMicah Weston EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference); 156e864ac69SMicah Weston 157e864ac69SMicah Weston Tokens = annotate("int f4() { return sizeof(Foo&&); }"); 158e864ac69SMicah Weston ASSERT_EQ(Tokens.size(), 14u) << Tokens; 159e864ac69SMicah Weston EXPECT_TOKEN(Tokens[9], tok::ampamp, TT_PointerOrReference); 160e864ac69SMicah Weston 161e864ac69SMicah Weston Tokens = annotate("void f5() { int f6(Foo&, Bar&); }"); 162e864ac69SMicah Weston ASSERT_EQ(Tokens.size(), 17u) << Tokens; 163e864ac69SMicah Weston EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference); 164e864ac69SMicah Weston EXPECT_TOKEN(Tokens[12], tok::amp, TT_PointerOrReference); 165e864ac69SMicah Weston 166e864ac69SMicah Weston Tokens = annotate("void f7() { int f8(Foo&&, Bar&&); }"); 167e864ac69SMicah Weston ASSERT_EQ(Tokens.size(), 17u) << Tokens; 168e864ac69SMicah Weston EXPECT_TOKEN(Tokens[9], tok::ampamp, TT_PointerOrReference); 169e864ac69SMicah Weston EXPECT_TOKEN(Tokens[12], tok::ampamp, TT_PointerOrReference); 17035f2ac17SDavid Turner 17135f2ac17SDavid Turner Tokens = annotate("Type1 &val1 = val2;"); 17235f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 7u) << Tokens; 17335f2ac17SDavid Turner EXPECT_TOKEN(Tokens[1], tok::amp, TT_PointerOrReference); 17435f2ac17SDavid Turner 17535f2ac17SDavid Turner Tokens = annotate("Type1 *val1 = &val2;"); 17635f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 8u) << Tokens; 17735f2ac17SDavid Turner EXPECT_TOKEN(Tokens[1], tok::star, TT_PointerOrReference); 17835f2ac17SDavid Turner EXPECT_TOKEN(Tokens[4], tok::amp, TT_UnaryOperator); 17935f2ac17SDavid Turner 18035f2ac17SDavid Turner Tokens = annotate("val1 & val2;"); 18135f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 5u) << Tokens; 18235f2ac17SDavid Turner EXPECT_TOKEN(Tokens[1], tok::amp, TT_BinaryOperator); 18335f2ac17SDavid Turner 18435f2ac17SDavid Turner Tokens = annotate("val1 & val2.member;"); 18535f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 7u) << Tokens; 18635f2ac17SDavid Turner EXPECT_TOKEN(Tokens[1], tok::amp, TT_BinaryOperator); 18735f2ac17SDavid Turner 18835f2ac17SDavid Turner Tokens = annotate("val1 & val2.*member;"); 18935f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 7u) << Tokens; 19035f2ac17SDavid Turner EXPECT_TOKEN(Tokens[1], tok::amp, TT_BinaryOperator); 19135f2ac17SDavid Turner 19235f2ac17SDavid Turner Tokens = annotate("val1.*member & val2;"); 19335f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 7u) << Tokens; 19435f2ac17SDavid Turner EXPECT_TOKEN(Tokens[3], tok::amp, TT_BinaryOperator); 19535f2ac17SDavid Turner 19635f2ac17SDavid Turner Tokens = annotate("val1 & val2->*member;"); 19735f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 7u) << Tokens; 19835f2ac17SDavid Turner EXPECT_TOKEN(Tokens[1], tok::amp, TT_BinaryOperator); 19935f2ac17SDavid Turner 20035f2ac17SDavid Turner Tokens = annotate("val1->member & val2;"); 20135f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 7u) << Tokens; 20235f2ac17SDavid Turner EXPECT_TOKEN(Tokens[3], tok::amp, TT_BinaryOperator); 20335f2ac17SDavid Turner 20435f2ac17SDavid Turner Tokens = annotate("val1 & val2 & val3;"); 20535f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 7u) << Tokens; 20635f2ac17SDavid Turner EXPECT_TOKEN(Tokens[1], tok::amp, TT_BinaryOperator); 20735f2ac17SDavid Turner EXPECT_TOKEN(Tokens[3], tok::amp, TT_BinaryOperator); 20835f2ac17SDavid Turner 20935f2ac17SDavid Turner Tokens = annotate("val1 & val2 // comment\n" 21035f2ac17SDavid Turner " & val3;"); 21135f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 8u) << Tokens; 21235f2ac17SDavid Turner EXPECT_TOKEN(Tokens[1], tok::amp, TT_BinaryOperator); 21335f2ac17SDavid Turner EXPECT_TOKEN(Tokens[4], tok::amp, TT_BinaryOperator); 21435f2ac17SDavid Turner 21535f2ac17SDavid Turner Tokens = 21635f2ac17SDavid Turner annotate("val1 & val2.member & val3.member() & val4 & val5->member;"); 21735f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 19u) << Tokens; 21835f2ac17SDavid Turner EXPECT_TOKEN(Tokens[1], tok::amp, TT_BinaryOperator); 21935f2ac17SDavid Turner EXPECT_TOKEN(Tokens[5], tok::amp, TT_BinaryOperator); 22035f2ac17SDavid Turner EXPECT_TOKEN(Tokens[11], tok::amp, TT_BinaryOperator); 22135f2ac17SDavid Turner EXPECT_TOKEN(Tokens[13], tok::amp, TT_BinaryOperator); 22235f2ac17SDavid Turner 22335f2ac17SDavid Turner Tokens = annotate("class c {\n" 22435f2ac17SDavid Turner " void func(type &a) { a & member; }\n" 22535f2ac17SDavid Turner " anotherType &member;\n" 22635f2ac17SDavid Turner "}"); 22735f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 22u) << Tokens; 22835f2ac17SDavid Turner EXPECT_TOKEN(Tokens[7], tok::amp, TT_PointerOrReference); 22935f2ac17SDavid Turner EXPECT_TOKEN(Tokens[12], tok::amp, TT_BinaryOperator); 23035f2ac17SDavid Turner EXPECT_TOKEN(Tokens[17], tok::amp, TT_PointerOrReference); 23135f2ac17SDavid Turner 23235f2ac17SDavid Turner Tokens = annotate("struct S {\n" 23335f2ac17SDavid Turner " auto Mem = C & D;\n" 23435f2ac17SDavid Turner "}"); 23535f2ac17SDavid Turner ASSERT_EQ(Tokens.size(), 12u) << Tokens; 23635f2ac17SDavid Turner EXPECT_TOKEN(Tokens[7], tok::amp, TT_BinaryOperator); 237ead96446SEmilia Dreamer 238ead96446SEmilia Dreamer Tokens = 239ead96446SEmilia Dreamer annotate("template <typename T> void swap() noexcept(Bar<T> && Foo<T>);"); 240ead96446SEmilia Dreamer ASSERT_EQ(Tokens.size(), 23u) << Tokens; 241ead96446SEmilia Dreamer EXPECT_TOKEN(Tokens[15], tok::ampamp, TT_BinaryOperator); 242ead96446SEmilia Dreamer 243ead96446SEmilia Dreamer Tokens = annotate("template <typename T> struct S {\n" 244ead96446SEmilia Dreamer " explicit(Bar<T> && Foo<T>) S(const S &);\n" 245ead96446SEmilia Dreamer "};"); 246ead96446SEmilia Dreamer ASSERT_EQ(Tokens.size(), 30u) << Tokens; 247ead96446SEmilia Dreamer EXPECT_TOKEN(Tokens[14], tok::ampamp, TT_BinaryOperator); 248bb4f6c4dSEmilia Dreamer 249bb4f6c4dSEmilia Dreamer Tokens = annotate("template <bool B = C && D> struct S {};"); 250bb4f6c4dSEmilia Dreamer ASSERT_EQ(Tokens.size(), 15u) << Tokens; 251bb4f6c4dSEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::ampamp, TT_BinaryOperator); 252bb4f6c4dSEmilia Dreamer 253bb4f6c4dSEmilia Dreamer Tokens = annotate("template <typename T, bool B = C && D> struct S {};"); 254bb4f6c4dSEmilia Dreamer ASSERT_EQ(Tokens.size(), 18u) << Tokens; 255bb4f6c4dSEmilia Dreamer EXPECT_TOKEN(Tokens[9], tok::ampamp, TT_BinaryOperator); 25650acd670SEmilia Dreamer 25750acd670SEmilia Dreamer Tokens = annotate("template <typename T, typename U = T&&> struct S {};"); 25850acd670SEmilia Dreamer ASSERT_EQ(Tokens.size(), 17u) << Tokens; 25950acd670SEmilia Dreamer EXPECT_TOKEN(Tokens[9], tok::ampamp, TT_PointerOrReference); 26050acd670SEmilia Dreamer 26150acd670SEmilia Dreamer Tokens = annotate("template <typename T = int (*)(int)> struct S {};"); 26250acd670SEmilia Dreamer ASSERT_EQ(Tokens.size(), 19u) << Tokens; 26350acd670SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen); 26450acd670SEmilia Dreamer EXPECT_TOKEN(Tokens[7], tok::star, TT_PointerOrReference); 2655dc94b33SEmilia Dreamer 2665dc94b33SEmilia Dreamer Tokens = annotate("Foo<A && B> a = {};"); 2675dc94b33SEmilia Dreamer ASSERT_EQ(Tokens.size(), 12u) << Tokens; 2685dc94b33SEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_BinaryOperator); 2695dc94b33SEmilia Dreamer 2705dc94b33SEmilia Dreamer Tokens = annotate("Foo<A &&> a = {};"); 2715dc94b33SEmilia Dreamer ASSERT_EQ(Tokens.size(), 11u) << Tokens; 2725dc94b33SEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference); 2735dc94b33SEmilia Dreamer 2748abdf7ccSOwen Pan Tokens = annotate("template <typename T>\n" 2758abdf7ccSOwen Pan "enable_if_t<is_integral_v<T>, bool> // comment\n" 2768abdf7ccSOwen Pan "operator~(T &a);"); 2778abdf7ccSOwen Pan ASSERT_EQ(Tokens.size(), 24u) << Tokens; 2788abdf7ccSOwen Pan EXPECT_TOKEN(Tokens[19], tok::amp, TT_PointerOrReference); 2798abdf7ccSOwen Pan 2805dc94b33SEmilia Dreamer Tokens = annotate("template <enable_if_t<foo && !bar>* = nullptr> void f();"); 2815dc94b33SEmilia Dreamer ASSERT_EQ(Tokens.size(), 19u) << Tokens; 2825dc94b33SEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::ampamp, TT_BinaryOperator); 2835c106f7bSOwen Pan 2844f7086ceSBjörn Schäpers Tokens = 2854f7086ceSBjörn Schäpers annotate("auto foo() noexcept(noexcept(bar()) && " 2864f7086ceSBjörn Schäpers "trait<std::decay_t<decltype(bar())>> && noexcept(baz())) {}"); 28788d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 38u) << Tokens; 2884f7086ceSBjörn Schäpers EXPECT_TOKEN(Tokens[12], tok::ampamp, TT_BinaryOperator); 2894f7086ceSBjörn Schäpers EXPECT_TOKEN(Tokens[27], tok::ampamp, TT_BinaryOperator); 2904f7086ceSBjörn Schäpers 2910b2c88eeSOwen Pan Tokens = annotate("foo = *i < *j && *j > *k;"); 29288d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 15u) << Tokens; 2930b2c88eeSOwen Pan EXPECT_TOKEN(Tokens[4], tok::less, TT_BinaryOperator); 2940b2c88eeSOwen Pan EXPECT_TOKEN(Tokens[7], tok::ampamp, TT_BinaryOperator); 2950b2c88eeSOwen Pan EXPECT_TOKEN(Tokens[10], tok::greater, TT_BinaryOperator); 2960b2c88eeSOwen Pan 297c28e268cSOwen Pan Tokens = annotate("if (Foo *foo; bar)"); 298c28e268cSOwen Pan ASSERT_EQ(Tokens.size(), 9u) << Tokens; 299c28e268cSOwen Pan EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference); 300c28e268cSOwen Pan 301c28e268cSOwen Pan Tokens = annotate("if (Foo **foo(); bar)"); 302c28e268cSOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 303c28e268cSOwen Pan EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference); 304c28e268cSOwen Pan EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference); 305c28e268cSOwen Pan 306c28e268cSOwen Pan Tokens = annotate("if (Foo *&foo{a}; bar)"); 307c28e268cSOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 308c28e268cSOwen Pan EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference); 309c28e268cSOwen Pan EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference); 310c28e268cSOwen Pan 3115c106f7bSOwen Pan FormatStyle Style = getLLVMStyle(); 3125c106f7bSOwen Pan Style.TypeNames.push_back("MYI"); 3135c106f7bSOwen Pan Tokens = annotate("if (MYI *p{nullptr})", Style); 3145c106f7bSOwen Pan ASSERT_EQ(Tokens.size(), 10u) << Tokens; 3155c106f7bSOwen Pan EXPECT_TOKEN(Tokens[2], tok::identifier, TT_TypeName); 3165c106f7bSOwen Pan EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference); 3175c106f7bSOwen Pan 3185c106f7bSOwen Pan Style.TypeNames.push_back("Class"); 3195c106f7bSOwen Pan Tokens = annotate("if (Class *obj {getObj()})", Style); 3205c106f7bSOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 3215c106f7bSOwen Pan EXPECT_TOKEN(Tokens[2], tok::identifier, TT_TypeName); 3225c106f7bSOwen Pan EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference); 3239512d6d2SXDeme 3249512d6d2SXDeme Tokens = annotate("class Foo {\n" 3259512d6d2SXDeme " void operator<() {}\n" 3269512d6d2SXDeme " Foo &f;\n" 3279512d6d2SXDeme "};"); 3289512d6d2SXDeme ASSERT_EQ(Tokens.size(), 17u) << Tokens; 3299512d6d2SXDeme EXPECT_TOKEN(Tokens[4], tok::kw_operator, TT_FunctionDeclarationName); 3309512d6d2SXDeme EXPECT_TOKEN(Tokens[5], tok::less, TT_OverloadedOperator); 3319512d6d2SXDeme EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_OverloadedOperatorLParen); 3329512d6d2SXDeme EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_FunctionLBrace); 3339512d6d2SXDeme EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference); 334b6cc6671SOwen Pan 335b6cc6671SOwen Pan Tokens = annotate("if (new && num) {\n" 336b6cc6671SOwen Pan " new = 1;\n" 337b6cc6671SOwen Pan "}\n" 338b6cc6671SOwen Pan "if (!delete && num) {\n" 339b6cc6671SOwen Pan " delete = 1;\n" 340b6cc6671SOwen Pan "}"); 341b6cc6671SOwen Pan ASSERT_EQ(Tokens.size(), 26u) << Tokens; 342b6cc6671SOwen Pan EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_BinaryOperator); 343b6cc6671SOwen Pan EXPECT_TOKEN(Tokens[16], tok::ampamp, TT_BinaryOperator); 344812c96e8SOwen Pan 345812c96e8SOwen Pan Tokens = annotate("#define FOO \\\n" 346812c96e8SOwen Pan " void foo() { f(a * b); }"); 347812c96e8SOwen Pan ASSERT_EQ(Tokens.size(), 17u) << Tokens; 348812c96e8SOwen Pan EXPECT_TOKEN(Tokens[11], tok::star, TT_BinaryOperator); 349812c96e8SOwen Pan 3504fd14b9aSOwen Pan Tokens = annotate("for (int i; Foo *&foo : foos)"); 3514fd14b9aSOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 3524fd14b9aSOwen Pan EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference); 3534fd14b9aSOwen Pan EXPECT_TOKEN(Tokens[7], tok::amp, TT_PointerOrReference); 3544fd14b9aSOwen Pan EXPECT_TOKEN(Tokens[9], tok::colon, TT_RangeBasedForLoopColon); 3554fd14b9aSOwen Pan 356812c96e8SOwen Pan Tokens = annotate("#define FOO auto Foo = [] { f(a * b); };"); 357812c96e8SOwen Pan ASSERT_EQ(Tokens.size(), 19u) << Tokens; 358812c96e8SOwen Pan EXPECT_TOKEN(Tokens[12], tok::star, TT_BinaryOperator); 359812c96e8SOwen Pan 360812c96e8SOwen Pan Tokens = annotate("namespace {\n" 361812c96e8SOwen Pan "#define FOO(x) void foo(a##x *b);\n" 362812c96e8SOwen Pan "}"); 363812c96e8SOwen Pan ASSERT_EQ(Tokens.size(), 20u) << Tokens; 364812c96e8SOwen Pan EXPECT_TOKEN(Tokens[14], tok::star, TT_PointerOrReference); 365eaff3a74SOwen Pan 366eaff3a74SOwen Pan Tokens = annotate("Thingy kConfig = {\n" 367eaff3a74SOwen Pan " 1,\n" 368eaff3a74SOwen Pan " (uint16_t)(kScale * height_pixels),\n" 369eaff3a74SOwen Pan "};"); 370eaff3a74SOwen Pan ASSERT_EQ(Tokens.size(), 18u) << Tokens; 371eaff3a74SOwen Pan EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_CastRParen); 372eaff3a74SOwen Pan EXPECT_TOKEN(Tokens[11], tok::star, TT_BinaryOperator); 3739e4774b9SOwen Pan 3749e4774b9SOwen Pan Tokens = annotate("template <typename T>\n" 3759e4774b9SOwen Pan "concept C = requires(T a, T b) { a && b; };"); 3769e4774b9SOwen Pan ASSERT_EQ(Tokens.size(), 24u) << Tokens; 3779e4774b9SOwen Pan EXPECT_TOKEN(Tokens[16], tok::l_brace, TT_RequiresExpressionLBrace); 3789e4774b9SOwen Pan EXPECT_TOKEN(Tokens[18], tok::ampamp, TT_BinaryOperator); 3799e4774b9SOwen Pan 3809e4774b9SOwen Pan Tokens = annotate("template <typename T, typename V>\n" 3819e4774b9SOwen Pan "concept CheckMultiplicableBy = requires(T a, V b) {\n" 3829e4774b9SOwen Pan " { a * b } -> std::same_as<T>;\n" 3839e4774b9SOwen Pan "};"); 3849e4774b9SOwen Pan ASSERT_EQ(Tokens.size(), 36u) << Tokens; 3859e4774b9SOwen Pan EXPECT_TOKEN(Tokens[19], tok::l_brace, TT_RequiresExpressionLBrace); 3869e4774b9SOwen Pan EXPECT_TOKEN(Tokens[20], tok::l_brace, TT_CompoundRequirementLBrace); 3879e4774b9SOwen Pan EXPECT_TOKEN(Tokens[22], tok::star, TT_BinaryOperator); 388c261f78dSsstwcw } 389c261f78dSsstwcw 390c261f78dSsstwcw TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) { 391c261f78dSsstwcw auto Tokens = annotate("x - 0"); 392c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 4u) << Tokens; 393c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::minus, TT_BinaryOperator); 394c261f78dSsstwcw Tokens = annotate("0 + 0"); 395c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 4u) << Tokens; 396c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::plus, TT_BinaryOperator); 397c261f78dSsstwcw Tokens = annotate("x + +0"); 398c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 399c261f78dSsstwcw EXPECT_TOKEN(Tokens[2], tok::plus, TT_UnaryOperator); 400c261f78dSsstwcw Tokens = annotate("x ? -0 : +0"); 401c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 8u) << Tokens; 402c261f78dSsstwcw EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator); 403c261f78dSsstwcw EXPECT_TOKEN(Tokens[5], tok::plus, TT_UnaryOperator); 404c261f78dSsstwcw Tokens = annotate("(-0)"); 405c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 406c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator); 407c261f78dSsstwcw Tokens = annotate("0, -0"); 408c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 409c261f78dSsstwcw EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator); 410c261f78dSsstwcw Tokens = annotate("for (; -1;) {\n}"); 411c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 10u) << Tokens; 412c261f78dSsstwcw EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator); 413c261f78dSsstwcw Tokens = annotate("x = -1;"); 414c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 6u) << Tokens; 415c261f78dSsstwcw EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator); 416c261f78dSsstwcw Tokens = annotate("x[-1]"); 417c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 6u) << Tokens; 418c261f78dSsstwcw EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator); 419c261f78dSsstwcw Tokens = annotate("x = {-1};"); 420c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 8u) << Tokens; 421c261f78dSsstwcw EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator); 422c261f78dSsstwcw Tokens = annotate("case -x:"); 423c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 424c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator); 425c261f78dSsstwcw Tokens = annotate("co_await -x;"); 426c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 427c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator); 428c261f78dSsstwcw Tokens = annotate("co_return -x;"); 429c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 430c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator); 431c261f78dSsstwcw Tokens = annotate("co_yield -x;"); 432c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 433c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator); 434c261f78dSsstwcw Tokens = annotate("delete -x;"); 435c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 436c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator); 437c261f78dSsstwcw Tokens = annotate("return -x;"); 438c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 439c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator); 440c261f78dSsstwcw Tokens = annotate("throw -x;"); 441c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 442c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator); 443c261f78dSsstwcw Tokens = annotate("sizeof -x"); 444c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 4u) << Tokens; 445c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator); 446c261f78dSsstwcw Tokens = annotate("co_await +x;"); 447c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 448c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator); 449c261f78dSsstwcw Tokens = annotate("co_return +x;"); 450c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 451c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator); 452c261f78dSsstwcw Tokens = annotate("co_yield +x;"); 453c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 454c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator); 455c261f78dSsstwcw Tokens = annotate("delete +x;"); 456c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 457c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator); 458c261f78dSsstwcw Tokens = annotate("return +x;"); 459c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 460c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator); 461c261f78dSsstwcw Tokens = annotate("throw +x;"); 462c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 463c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator); 464c261f78dSsstwcw Tokens = annotate("sizeof +x"); 465c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 4u) << Tokens; 466c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator); 467c261f78dSsstwcw Tokens = annotate("(int)-x"); 468c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 6u) << Tokens; 469c261f78dSsstwcw EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator); 470c261f78dSsstwcw Tokens = annotate("(-x)"); 471c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 472c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator); 473c261f78dSsstwcw Tokens = annotate("!+x"); 474c261f78dSsstwcw ASSERT_EQ(Tokens.size(), 4u) << Tokens; 475c261f78dSsstwcw EXPECT_TOKEN(Tokens[0], tok::exclaim, TT_UnaryOperator); 476c261f78dSsstwcw EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator); 47785032534SAlex Richardson } 47885032534SAlex Richardson 47936622c4eSMarek Kurdej TEST_F(TokenAnnotatorTest, UnderstandsClasses) { 48036622c4eSMarek Kurdej auto Tokens = annotate("class C {};"); 48188d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 6u) << Tokens; 482d81f003cSMarek Kurdej EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_ClassLBrace); 48338c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::r_brace, TT_ClassRBrace); 484d81f003cSMarek Kurdej 485d81f003cSMarek Kurdej Tokens = annotate("const class C {} c;"); 48688d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 8u) << Tokens; 487d81f003cSMarek Kurdej EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_ClassLBrace); 48838c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_ClassRBrace); 489d81f003cSMarek Kurdej 490d81f003cSMarek Kurdej Tokens = annotate("const class {} c;"); 49188d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 7u) << Tokens; 492d81f003cSMarek Kurdej EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_ClassLBrace); 49338c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::r_brace, TT_ClassRBrace); 494a02c3af9SOwen Pan 495a02c3af9SOwen Pan Tokens = annotate("class [[deprecated(\"\")]] C { int i; };"); 49688d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 17u) << Tokens; 497a02c3af9SOwen Pan EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_ClassLBrace); 49838c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[14], tok::r_brace, TT_ClassRBrace); 49936622c4eSMarek Kurdej } 50036622c4eSMarek Kurdej 50136622c4eSMarek Kurdej TEST_F(TokenAnnotatorTest, UnderstandsStructs) { 50236622c4eSMarek Kurdej auto Tokens = annotate("struct S {};"); 50388d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 6u) << Tokens; 504d81f003cSMarek Kurdej EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_StructLBrace); 50538c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::r_brace, TT_StructRBrace); 506767aee1dSOwen Pan 5078e9b1e9aSOwen Pan Tokens = annotate("struct macro(a) S {};"); 5088e9b1e9aSOwen Pan ASSERT_EQ(Tokens.size(), 10u) << Tokens; 5098e9b1e9aSOwen Pan EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_StructLBrace); 5108e9b1e9aSOwen Pan EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_StructRBrace); 5118e9b1e9aSOwen Pan 512767aee1dSOwen Pan Tokens = annotate("struct EXPORT_MACRO [[nodiscard]] C { int i; };"); 51388d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 15u) << Tokens; 514767aee1dSOwen Pan EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_StructLBrace); 51538c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[12], tok::r_brace, TT_StructRBrace); 516767aee1dSOwen Pan 517767aee1dSOwen Pan Tokens = annotate("struct [[deprecated]] [[nodiscard]] C { int i; };"); 51888d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 19u) << Tokens; 519767aee1dSOwen Pan EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_StructLBrace); 52038c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[16], tok::r_brace, TT_StructRBrace); 5212a42a7b4SOwen Pan 5228e9b1e9aSOwen Pan Tokens = annotate("struct macro(a) S {\n" 5238e9b1e9aSOwen Pan " void f(T &t);\n" 5248e9b1e9aSOwen Pan "};"); 5258e9b1e9aSOwen Pan ASSERT_EQ(Tokens.size(), 18u) << Tokens; 5268e9b1e9aSOwen Pan EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_StructLBrace); 5278e9b1e9aSOwen Pan EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference); 5288e9b1e9aSOwen Pan EXPECT_TOKEN(Tokens[15], tok::r_brace, TT_StructRBrace); 5298e9b1e9aSOwen Pan 5302a42a7b4SOwen Pan Tokens = annotate("template <typename T> struct S<const T[N]> {};"); 53188d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 18u) << Tokens; 5322a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[7], tok::less, TT_TemplateOpener); 5332a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[10], tok::l_square, TT_ArraySubscriptLSquare); 5342a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser); 5352a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[14], tok::l_brace, TT_StructLBrace); 53638c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[15], tok::r_brace, TT_StructRBrace); 5372a42a7b4SOwen Pan 5382a42a7b4SOwen Pan Tokens = annotate("template <typename T> struct S<T const[N]> {};"); 53988d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 18u) << Tokens; 5402a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[7], tok::less, TT_TemplateOpener); 5412a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[10], tok::l_square, TT_ArraySubscriptLSquare); 5422a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser); 5432a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[14], tok::l_brace, TT_StructLBrace); 54438c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[15], tok::r_brace, TT_StructRBrace); 5452a42a7b4SOwen Pan 5462a42a7b4SOwen Pan Tokens = annotate("template <typename T, unsigned n> struct S<T const[n]> {\n" 5472a42a7b4SOwen Pan " void f(T const (&a)[n]);\n" 5482a42a7b4SOwen Pan "};"); 54988d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 35u) << Tokens; 5502a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[10], tok::less, TT_TemplateOpener); 5512a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[13], tok::l_square, TT_ArraySubscriptLSquare); 5522a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[16], tok::greater, TT_TemplateCloser); 5532a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[17], tok::l_brace, TT_StructLBrace); 5542a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[23], tok::l_paren, TT_FunctionTypeLParen); 5552a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[24], tok::amp, TT_UnaryOperator); 5562a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[27], tok::l_square, TT_ArraySubscriptLSquare); 55738c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[32], tok::r_brace, TT_StructRBrace); 558c609043dSEmilia Kond 559c609043dSEmilia Kond Tokens = annotate("template <typename T, enum E e> struct S {};"); 560c609043dSEmilia Kond ASSERT_EQ(Tokens.size(), 15u) << Tokens; 561c609043dSEmilia Kond EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_StructLBrace); 56213f67978SOwen Pan 5639452ee4fSOwen Pan constexpr StringRef Code{"struct EXPORT StructName {};"}; 5649452ee4fSOwen Pan 5659452ee4fSOwen Pan Tokens = annotate(Code); 5669452ee4fSOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 5679452ee4fSOwen Pan EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_StructLBrace); 5689452ee4fSOwen Pan EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_StructRBrace); 5699452ee4fSOwen Pan 57013f67978SOwen Pan auto Style = getLLVMStyle(); 57113f67978SOwen Pan Style.AttributeMacros.push_back("EXPORT"); 5729452ee4fSOwen Pan Tokens = annotate(Code, Style); 57313f67978SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 57413f67978SOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_AttributeMacro); 57513f67978SOwen Pan EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_StructLBrace); 57613f67978SOwen Pan EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_StructRBrace); 57736622c4eSMarek Kurdej } 57836622c4eSMarek Kurdej 57936622c4eSMarek Kurdej TEST_F(TokenAnnotatorTest, UnderstandsUnions) { 58036622c4eSMarek Kurdej auto Tokens = annotate("union U {};"); 58188d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 6u) << Tokens; 582d81f003cSMarek Kurdej EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_UnionLBrace); 58338c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::r_brace, TT_UnionRBrace); 584d81f003cSMarek Kurdej 585d81f003cSMarek Kurdej Tokens = annotate("union U { void f() { return; } };"); 58688d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 14u) << Tokens; 587d81f003cSMarek Kurdej EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_UnionLBrace); 588d81f003cSMarek Kurdej EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_FunctionLBrace); 58938c31d7eSBjörn Schäpers EXPECT_TOKEN(Tokens[11], tok::r_brace, TT_UnionRBrace); 59036622c4eSMarek Kurdej } 59136622c4eSMarek Kurdej 59236622c4eSMarek Kurdej TEST_F(TokenAnnotatorTest, UnderstandsEnums) { 59336622c4eSMarek Kurdej auto Tokens = annotate("enum E {};"); 59488d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 6u) << Tokens; 595d81f003cSMarek Kurdej EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_EnumLBrace); 596b7abab2fSBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::r_brace, TT_EnumRBrace); 59736622c4eSMarek Kurdej } 59836622c4eSMarek Kurdej 5993227aa3aSMarek Kurdej TEST_F(TokenAnnotatorTest, UnderstandsDefaultedAndDeletedFunctions) { 6003227aa3aSMarek Kurdej auto Tokens = annotate("auto operator<=>(const T &) const & = default;"); 60188d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 14u) << Tokens; 6023227aa3aSMarek Kurdej EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference); 6033227aa3aSMarek Kurdej 6043227aa3aSMarek Kurdej Tokens = annotate("template <typename T> void F(T) && = delete;"); 60588d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 15u) << Tokens; 6063227aa3aSMarek Kurdej EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_PointerOrReference); 6073227aa3aSMarek Kurdej } 6083227aa3aSMarek Kurdej 6093227aa3aSMarek Kurdej TEST_F(TokenAnnotatorTest, UnderstandsVariables) { 6103227aa3aSMarek Kurdej auto Tokens = 6113227aa3aSMarek Kurdej annotate("inline bool var = is_integral_v<int> && is_signed_v<int>;"); 61288d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 15u) << Tokens; 6133227aa3aSMarek Kurdej EXPECT_TOKEN(Tokens[8], tok::ampamp, TT_BinaryOperator); 6143227aa3aSMarek Kurdej } 6153227aa3aSMarek Kurdej 6163227aa3aSMarek Kurdej TEST_F(TokenAnnotatorTest, UnderstandsVariableTemplates) { 6173227aa3aSMarek Kurdej auto Tokens = 6183227aa3aSMarek Kurdej annotate("template <typename T> " 6193227aa3aSMarek Kurdej "inline bool var = is_integral_v<int> && is_signed_v<int>;"); 62088d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 20u) << Tokens; 6213227aa3aSMarek Kurdej EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_BinaryOperator); 6223227aa3aSMarek Kurdej } 6233227aa3aSMarek Kurdej 624e5964223Ssstwcw TEST_F(TokenAnnotatorTest, UnderstandsTemplatesInMacros) { 625e5964223Ssstwcw auto Tokens = 626e5964223Ssstwcw annotate("#define FOO(typeName) \\\n" 627e5964223Ssstwcw " { #typeName, foo<FooType>(new foo<realClass>(#typeName)) }"); 628e5964223Ssstwcw ASSERT_EQ(Tokens.size(), 27u) << Tokens; 629e5964223Ssstwcw EXPECT_TOKEN(Tokens[11], tok::less, TT_TemplateOpener); 630e5964223Ssstwcw EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser); 631e5964223Ssstwcw EXPECT_TOKEN(Tokens[17], tok::less, TT_TemplateOpener); 632e5964223Ssstwcw EXPECT_TOKEN(Tokens[19], tok::greater, TT_TemplateCloser); 633e5964223Ssstwcw } 634e5964223Ssstwcw 635b62906b0SBackl1ght TEST_F(TokenAnnotatorTest, UnderstandsGreaterAfterTemplateCloser) { 636b62906b0SBackl1ght auto Tokens = annotate("if (std::tuple_size_v<T> > 0)"); 637b62906b0SBackl1ght ASSERT_EQ(Tokens.size(), 12u) << Tokens; 638b62906b0SBackl1ght EXPECT_TOKEN(Tokens[5], tok::less, TT_TemplateOpener); 639b62906b0SBackl1ght EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser); 640b62906b0SBackl1ght EXPECT_TOKEN(Tokens[8], tok::greater, TT_BinaryOperator); 641b62906b0SBackl1ght } 642b62906b0SBackl1ght 643834ac2e2SEmilia Kond TEST_F(TokenAnnotatorTest, UnderstandsTernaryInTemplate) { 644834ac2e2SEmilia Kond // IsExpression = false 645834ac2e2SEmilia Kond auto Tokens = annotate("foo<true ? 1 : 2>();"); 646834ac2e2SEmilia Kond ASSERT_EQ(Tokens.size(), 12u) << Tokens; 647834ac2e2SEmilia Kond EXPECT_TOKEN(Tokens[1], tok::less, TT_TemplateOpener); 648834ac2e2SEmilia Kond EXPECT_TOKEN(Tokens[3], tok::question, TT_ConditionalExpr); 649834ac2e2SEmilia Kond EXPECT_TOKEN(Tokens[5], tok::colon, TT_ConditionalExpr); 650834ac2e2SEmilia Kond EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser); 651834ac2e2SEmilia Kond 652834ac2e2SEmilia Kond // IsExpression = true 65373c961a3SOwen Pan 654834ac2e2SEmilia Kond Tokens = annotate("return foo<true ? 1 : 2>();"); 655834ac2e2SEmilia Kond ASSERT_EQ(Tokens.size(), 13u) << Tokens; 656834ac2e2SEmilia Kond EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 657834ac2e2SEmilia Kond EXPECT_TOKEN(Tokens[4], tok::question, TT_ConditionalExpr); 658834ac2e2SEmilia Kond EXPECT_TOKEN(Tokens[6], tok::colon, TT_ConditionalExpr); 659834ac2e2SEmilia Kond EXPECT_TOKEN(Tokens[8], tok::greater, TT_TemplateCloser); 66073c961a3SOwen Pan 66173c961a3SOwen Pan Tokens = annotate("return foo<true ? 1 : 2>{};"); 66273c961a3SOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 66373c961a3SOwen Pan EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 66473c961a3SOwen Pan EXPECT_TOKEN(Tokens[4], tok::question, TT_ConditionalExpr); 66573c961a3SOwen Pan EXPECT_TOKEN(Tokens[6], tok::colon, TT_ConditionalExpr); 66673c961a3SOwen Pan EXPECT_TOKEN(Tokens[8], tok::greater, TT_TemplateCloser); 667834ac2e2SEmilia Kond } 668834ac2e2SEmilia Kond 669e4d3e888SEmilia Kond TEST_F(TokenAnnotatorTest, UnderstandsNonTemplateAngleBrackets) { 670e4d3e888SEmilia Kond auto Tokens = annotate("return a < b && c > d;"); 671e4d3e888SEmilia Kond ASSERT_EQ(Tokens.size(), 10u) << Tokens; 672e4d3e888SEmilia Kond EXPECT_TOKEN(Tokens[2], tok::less, TT_BinaryOperator); 673e4d3e888SEmilia Kond EXPECT_TOKEN(Tokens[6], tok::greater, TT_BinaryOperator); 674e4d3e888SEmilia Kond 675e4d3e888SEmilia Kond Tokens = annotate("a < 0 ? b : a > 0 ? c : d;"); 676e4d3e888SEmilia Kond ASSERT_EQ(Tokens.size(), 15u) << Tokens; 677e4d3e888SEmilia Kond EXPECT_TOKEN(Tokens[1], tok::less, TT_BinaryOperator); 678e4d3e888SEmilia Kond EXPECT_TOKEN(Tokens[7], tok::greater, TT_BinaryOperator); 679e4d3e888SEmilia Kond 68073c961a3SOwen Pan Tokens = annotate("return A < B ? true : A > B;"); 68173c961a3SOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 68273c961a3SOwen Pan EXPECT_TOKEN(Tokens[2], tok::less, TT_BinaryOperator); 68373c961a3SOwen Pan EXPECT_TOKEN(Tokens[8], tok::greater, TT_BinaryOperator); 68473c961a3SOwen Pan 68573c961a3SOwen Pan Tokens = annotate("return A < B ? true : A > B ? false : false;"); 68673c961a3SOwen Pan ASSERT_EQ(Tokens.size(), 16u) << Tokens; 68773c961a3SOwen Pan EXPECT_TOKEN(Tokens[2], tok::less, TT_BinaryOperator); 68873c961a3SOwen Pan EXPECT_TOKEN(Tokens[8], tok::greater, TT_BinaryOperator); 68973c961a3SOwen Pan 6900916ae49SOwen Pan Tokens = annotate("return checklower ? a < b : a > b;"); 6910916ae49SOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 6920916ae49SOwen Pan EXPECT_TOKEN(Tokens[4], tok::less, TT_BinaryOperator); 6930916ae49SOwen Pan EXPECT_TOKEN(Tokens[8], tok::greater, TT_BinaryOperator); 6940916ae49SOwen Pan 695*1e89355dSOwen Pan Tokens = annotate("return A < B != A > B;"); 69673c961a3SOwen Pan ASSERT_EQ(Tokens.size(), 10u) << Tokens; 69773c961a3SOwen Pan EXPECT_TOKEN(Tokens[2], tok::less, TT_BinaryOperator); 69873c961a3SOwen Pan EXPECT_TOKEN(Tokens[6], tok::greater, TT_BinaryOperator); 69973c961a3SOwen Pan 700e4d3e888SEmilia Kond Tokens = annotate("ratio{-1, 2} < ratio{-1, 3} == -1 / 3 > -1 / 2;"); 701e4d3e888SEmilia Kond ASSERT_EQ(Tokens.size(), 27u) << Tokens; 702e4d3e888SEmilia Kond EXPECT_TOKEN(Tokens[7], tok::less, TT_BinaryOperator); 703e4d3e888SEmilia Kond EXPECT_TOKEN(Tokens[20], tok::greater, TT_BinaryOperator); 704e4d3e888SEmilia Kond } 705e4d3e888SEmilia Kond 7066621505aSEmilia Kond TEST_F(TokenAnnotatorTest, UnderstandsTemplateTemplateParameters) { 7076621505aSEmilia Kond auto Tokens = annotate("template <template <typename...> typename X,\n" 7086621505aSEmilia Kond " template <typename...> class Y,\n" 7096621505aSEmilia Kond " typename... T>\n" 7106621505aSEmilia Kond "class A {};"); 7116621505aSEmilia Kond ASSERT_EQ(Tokens.size(), 28u) << Tokens; 7126621505aSEmilia Kond EXPECT_TOKEN(Tokens[1], tok::less, TT_TemplateOpener); 7136621505aSEmilia Kond EXPECT_TOKEN(Tokens[3], tok::less, TT_TemplateOpener); 7146621505aSEmilia Kond EXPECT_TOKEN(Tokens[6], tok::greater, TT_TemplateCloser); 7156621505aSEmilia Kond EXPECT_FALSE(Tokens[6]->ClosesTemplateDeclaration); 7166621505aSEmilia Kond EXPECT_TOKEN(Tokens[11], tok::less, TT_TemplateOpener); 7176621505aSEmilia Kond EXPECT_TOKEN(Tokens[14], tok::greater, TT_TemplateCloser); 7186621505aSEmilia Kond EXPECT_FALSE(Tokens[14]->ClosesTemplateDeclaration); 7196621505aSEmilia Kond EXPECT_TOKEN(Tokens[21], tok::greater, TT_TemplateCloser); 7206621505aSEmilia Kond EXPECT_TRUE(Tokens[21]->ClosesTemplateDeclaration); 7216621505aSEmilia Kond } 7226621505aSEmilia Kond 7232e361207Sowenca TEST_F(TokenAnnotatorTest, UnderstandsWhitespaceSensitiveMacros) { 7242e361207Sowenca FormatStyle Style = getLLVMStyle(); 7252e361207Sowenca Style.WhitespaceSensitiveMacros.push_back("FOO"); 7262e361207Sowenca 72788934a82SOwen Pan auto Tokens = annotate("FOO(1+2 )", Style); 72888d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 7u) << Tokens; 7292e361207Sowenca EXPECT_TOKEN(Tokens[0], tok::identifier, TT_UntouchableMacroFunc); 7302e361207Sowenca 73188934a82SOwen Pan Tokens = annotate("FOO(a:b:c)", Style); 73288d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 9u) << Tokens; 7332e361207Sowenca EXPECT_TOKEN(Tokens[0], tok::identifier, TT_UntouchableMacroFunc); 7342e361207Sowenca } 7352e361207Sowenca 736a77c67f9SMarek Kurdej TEST_F(TokenAnnotatorTest, UnderstandsDelete) { 737a77c67f9SMarek Kurdej auto Tokens = annotate("delete (void *)p;"); 73888d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 8u) << Tokens; 739a77c67f9SMarek Kurdej EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_CastRParen); 740a77c67f9SMarek Kurdej 741a77c67f9SMarek Kurdej Tokens = annotate("delete[] (void *)p;"); 74288d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 10u) << Tokens; 743a77c67f9SMarek Kurdej EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_CastRParen); 744a77c67f9SMarek Kurdej 745a77c67f9SMarek Kurdej Tokens = annotate("delete[] /*comment*/ (void *)p;"); 74688d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 11u) << Tokens; 747a77c67f9SMarek Kurdej EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen); 748a77c67f9SMarek Kurdej 749a77c67f9SMarek Kurdej Tokens = annotate("delete[/*comment*/] (void *)p;"); 75088d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 11u) << Tokens; 751a77c67f9SMarek Kurdej EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen); 752a77c67f9SMarek Kurdej 753a77c67f9SMarek Kurdej Tokens = annotate("delete/*comment*/[] (void *)p;"); 75488d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 11u) << Tokens; 755a77c67f9SMarek Kurdej EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen); 756a77c67f9SMarek Kurdej } 757a77c67f9SMarek Kurdej 758c6e7752fSEmilia Dreamer TEST_F(TokenAnnotatorTest, UnderstandsCasts) { 759c6e7752fSEmilia Dreamer auto Tokens = annotate("(void)p;"); 76088d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 6u) << Tokens; 761c6e7752fSEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::r_paren, TT_CastRParen); 762c6e7752fSEmilia Dreamer 763c455b462SOwen Pan Tokens = annotate("(uint32_t)&&label;"); 764c455b462SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 765c455b462SOwen Pan EXPECT_TOKEN(Tokens[2], tok::r_paren, TT_CastRParen); 766c455b462SOwen Pan EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_UnaryOperator); 767c455b462SOwen Pan EXPECT_TOKEN(Tokens[4], tok::identifier, TT_Unknown); 768c455b462SOwen Pan 769c6e7752fSEmilia Dreamer Tokens = annotate("auto x = (Foo)p;"); 77088d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 9u) << Tokens; 771c6e7752fSEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_CastRParen); 772c6e7752fSEmilia Dreamer 773c6e7752fSEmilia Dreamer Tokens = annotate("(std::vector<int>)p;"); 77488d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 11u) << Tokens; 775c6e7752fSEmilia Dreamer EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen); 776c6e7752fSEmilia Dreamer 777c6e7752fSEmilia Dreamer Tokens = annotate("return (Foo)p;"); 77888d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 7u) << Tokens; 779c6e7752fSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen); 780c6e7752fSEmilia Dreamer 781c6e7752fSEmilia Dreamer Tokens = annotate("throw (Foo)p;"); 78288d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 7u) << Tokens; 783c6e7752fSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen); 7847a4cdbeaSOwen Pan 7857a4cdbeaSOwen Pan Tokens = annotate("#define FOO(x) (((uint64_t)(x) * BAR) / 100)"); 78688d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 21u) << Tokens; 7877a4cdbeaSOwen Pan EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_CastRParen); 7887a4cdbeaSOwen Pan EXPECT_TOKEN(Tokens[13], tok::r_paren, TT_Unknown); 7897a4cdbeaSOwen Pan EXPECT_TOKEN(Tokens[14], tok::star, TT_BinaryOperator); 7907a4cdbeaSOwen Pan 791f826f55bSOwen Pan Tokens = annotate("#define foo(i) ((i) - bar)"); 792f826f55bSOwen Pan ASSERT_EQ(Tokens.size(), 14u) << Tokens; 793f826f55bSOwen Pan EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_Unknown); 794f826f55bSOwen Pan EXPECT_TOKEN(Tokens[10], tok::minus, TT_BinaryOperator); 795f826f55bSOwen Pan 7967a4cdbeaSOwen Pan Tokens = annotate("return (Foo) & 10;"); 79788d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 8u) << Tokens; 7987a4cdbeaSOwen Pan EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_Unknown); 7997a4cdbeaSOwen Pan EXPECT_TOKEN(Tokens[4], tok::amp, TT_BinaryOperator); 8000baef3b1SOwen Pan 801d69050d6SOwen Pan Tokens = annotate("return (struct foo){};"); 802d69050d6SOwen Pan ASSERT_EQ(Tokens.size(), 9u) << Tokens; 803d69050d6SOwen Pan EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_CastRParen); 804d69050d6SOwen Pan 8050baef3b1SOwen Pan Tokens = annotate("#define FOO(bar) foo((uint64_t)&bar)"); 8060baef3b1SOwen Pan ASSERT_EQ(Tokens.size(), 15u) << Tokens; 8070baef3b1SOwen Pan EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_CastRParen); 8080baef3b1SOwen Pan EXPECT_TOKEN(Tokens[11], tok::amp, TT_UnaryOperator); 8090baef3b1SOwen Pan 8100baef3b1SOwen Pan Tokens = annotate("#define FOO(bar) foo((Foo) & bar)"); 8110baef3b1SOwen Pan ASSERT_EQ(Tokens.size(), 15u) << Tokens; 8120baef3b1SOwen Pan EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_Unknown); 8130baef3b1SOwen Pan EXPECT_TOKEN(Tokens[11], tok::amp, TT_BinaryOperator); 8140baef3b1SOwen Pan 8158c7a038fSOwen Pan Tokens = annotate("func((void (*)())&a);"); 8168c7a038fSOwen Pan ASSERT_EQ(Tokens.size(), 15u) << Tokens; 8178c7a038fSOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_FunctionTypeLParen); 8188c7a038fSOwen Pan EXPECT_TOKEN(Tokens[5], tok::star, TT_PointerOrReference); 8198c7a038fSOwen Pan EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_CastRParen); 8208c7a038fSOwen Pan EXPECT_TOKEN(Tokens[10], tok::amp, TT_UnaryOperator); 8218c7a038fSOwen Pan 8226bc225e0SOwen Pan Tokens = annotate("int result = ((int)a) - b;"); 8236bc225e0SOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 8246bc225e0SOwen Pan EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_CastRParen); 8256bc225e0SOwen Pan EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown); 8266bc225e0SOwen Pan EXPECT_TOKEN(Tokens[9], tok::minus, TT_BinaryOperator); 8276bc225e0SOwen Pan 828bcd586b5SOwen Pan Tokens = annotate("return (double)(foo(30)) - 15;"); 829bcd586b5SOwen Pan ASSERT_EQ(Tokens.size(), 14u) << Tokens; 830bcd586b5SOwen Pan EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen); 831bcd586b5SOwen Pan EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_Unknown); 832bcd586b5SOwen Pan EXPECT_TOKEN(Tokens[10], tok::minus, TT_BinaryOperator); 833bcd586b5SOwen Pan 8344d18ce1dSOwen Pan Tokens = annotate("return (::Type)(1 + 2);"); 8354d18ce1dSOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 8364d18ce1dSOwen Pan EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_CastRParen); 8374d18ce1dSOwen Pan 8384d18ce1dSOwen Pan Tokens = annotate("return (Namespace::Class)(1 + 2);"); 8394d18ce1dSOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 8404d18ce1dSOwen Pan EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_CastRParen); 8414d18ce1dSOwen Pan 8426ae14c05SOwen Pan Tokens = annotate("return (Foo (*)(void *, Bar, ...))&foo;"); 8436ae14c05SOwen Pan ASSERT_EQ(Tokens.size(), 19u) << Tokens; 8446ae14c05SOwen Pan EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_FunctionTypeLParen); 8456ae14c05SOwen Pan EXPECT_TOKEN(Tokens[14], tok::r_paren, TT_CastRParen); 8466ae14c05SOwen Pan EXPECT_TOKEN(Tokens[15], tok::amp, TT_UnaryOperator); 8476ae14c05SOwen Pan 8480baef3b1SOwen Pan auto Style = getLLVMStyle(); 8490baef3b1SOwen Pan Style.TypeNames.push_back("Foo"); 8500baef3b1SOwen Pan Tokens = annotate("#define FOO(bar) foo((Foo)&bar)", Style); 8510baef3b1SOwen Pan ASSERT_EQ(Tokens.size(), 15u) << Tokens; 8520baef3b1SOwen Pan EXPECT_TOKEN(Tokens[9], tok::identifier, TT_TypeName); 8530baef3b1SOwen Pan EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_CastRParen); 8540baef3b1SOwen Pan EXPECT_TOKEN(Tokens[11], tok::amp, TT_UnaryOperator); 855c6e7752fSEmilia Dreamer } 856c6e7752fSEmilia Dreamer 857c6e7752fSEmilia Dreamer TEST_F(TokenAnnotatorTest, UnderstandsDynamicExceptionSpecifier) { 858c6e7752fSEmilia Dreamer auto Tokens = annotate("void f() throw(int);"); 85988d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 10u) << Tokens; 860c6e7752fSEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::kw_throw, TT_Unknown); 861c6e7752fSEmilia Dreamer } 862c6e7752fSEmilia Dreamer 863e60defb9SMarek Kurdej TEST_F(TokenAnnotatorTest, UnderstandsFunctionRefQualifiers) { 864e60defb9SMarek Kurdej auto Tokens = annotate("void f() &;"); 86588d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 7u) << Tokens; 866e60defb9SMarek Kurdej EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference); 867e60defb9SMarek Kurdej 8683227aa3aSMarek Kurdej Tokens = annotate("void operator=(T) &&;"); 86988d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 9u) << Tokens; 8703227aa3aSMarek Kurdej EXPECT_TOKEN(Tokens[6], tok::ampamp, TT_PointerOrReference); 871e60defb9SMarek Kurdej 872e60defb9SMarek Kurdej Tokens = annotate("template <typename T> void f() &;"); 87388d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 12u) << Tokens; 874e60defb9SMarek Kurdej EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference); 875e60defb9SMarek Kurdej 8763227aa3aSMarek Kurdej Tokens = annotate("template <typename T> void operator=(T) &;"); 87788d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 14u) << Tokens; 8783227aa3aSMarek Kurdej EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference); 879e60defb9SMarek Kurdej } 880e60defb9SMarek Kurdej 881dce5bb9aSEmilia Dreamer TEST_F(TokenAnnotatorTest, UnderstandsOverloadedOperators) { 882dce5bb9aSEmilia Dreamer auto Tokens = annotate("x.operator+()"); 883dce5bb9aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 7u) << Tokens; 8843f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown); 885dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::plus, TT_OverloadedOperator); 886dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen); 887dce5bb9aSEmilia Dreamer Tokens = annotate("x.operator=()"); 888dce5bb9aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 7u) << Tokens; 8893f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown); 890dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::equal, TT_OverloadedOperator); 891dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen); 892dce5bb9aSEmilia Dreamer Tokens = annotate("x.operator+=()"); 893dce5bb9aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 7u) << Tokens; 8943f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown); 895dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::plusequal, TT_OverloadedOperator); 896dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen); 897dce5bb9aSEmilia Dreamer Tokens = annotate("x.operator,()"); 898dce5bb9aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 7u) << Tokens; 8993f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown); 900dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::comma, TT_OverloadedOperator); 901dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen); 902dce5bb9aSEmilia Dreamer Tokens = annotate("x.operator()()"); 903dce5bb9aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 8u) << Tokens; 9043f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown); 905dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperator); 906dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_OverloadedOperator); 907dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen); 908dce5bb9aSEmilia Dreamer Tokens = annotate("x.operator[]()"); 909dce5bb9aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 8u) << Tokens; 9103f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown); 911dce5bb9aSEmilia Dreamer // EXPECT_TOKEN(Tokens[3], tok::l_square, TT_OverloadedOperator); 912dce5bb9aSEmilia Dreamer // EXPECT_TOKEN(Tokens[4], tok::r_square, TT_OverloadedOperator); 913dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen); 914dce5bb9aSEmilia Dreamer Tokens = annotate("x.operator\"\"_a()"); 915dce5bb9aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 7u) << Tokens; 9163f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown); 917dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator); 918dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen); 919dce5bb9aSEmilia Dreamer Tokens = annotate("x.operator\"\" _a()"); 920dce5bb9aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 8u) << Tokens; 9213f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown); 922dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator); 923dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen); 924dce5bb9aSEmilia Dreamer Tokens = annotate("x.operator\"\"if()"); 925dce5bb9aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 7u) << Tokens; 9263f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown); 927dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator); 928dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen); 929dce5bb9aSEmilia Dreamer Tokens = annotate("x.operator\"\"s()"); 930dce5bb9aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 7u) << Tokens; 9313f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown); 932dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator); 933dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen); 934dce5bb9aSEmilia Dreamer Tokens = annotate("x.operator\"\" s()"); 935dce5bb9aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 8u) << Tokens; 9363f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_Unknown); 937dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator); 938dce5bb9aSEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen); 93948a932e1SEmilia Dreamer 94048a932e1SEmilia Dreamer Tokens = annotate("int operator+(int);"); 94148a932e1SEmilia Dreamer ASSERT_EQ(Tokens.size(), 8u) << Tokens; 94248a932e1SEmilia Dreamer EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName); 94348a932e1SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::plus, TT_OverloadedOperator); 94448a932e1SEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperatorLParen); 94548a932e1SEmilia Dreamer Tokens = annotate("auto operator=(T&) {}"); 94648a932e1SEmilia Dreamer ASSERT_EQ(Tokens.size(), 10u) << Tokens; 94748a932e1SEmilia Dreamer EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName); 94848a932e1SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::equal, TT_OverloadedOperator); 94948a932e1SEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperatorLParen); 95048a932e1SEmilia Dreamer Tokens = annotate("auto operator()() {}"); 95148a932e1SEmilia Dreamer ASSERT_EQ(Tokens.size(), 9u) << Tokens; 95248a932e1SEmilia Dreamer EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName); 95348a932e1SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_OverloadedOperator); 95448a932e1SEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_OverloadedOperator); 95548a932e1SEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen); 9564986f3f2SEmilia Kond 9574986f3f2SEmilia Kond Tokens = annotate("class Foo {\n" 9584986f3f2SEmilia Kond " int operator+(a* b);\n" 9594986f3f2SEmilia Kond "}"); 9604986f3f2SEmilia Kond ASSERT_EQ(Tokens.size(), 14u) << Tokens; 9614986f3f2SEmilia Kond EXPECT_TOKEN(Tokens[4], tok::kw_operator, TT_FunctionDeclarationName); 9624986f3f2SEmilia Kond EXPECT_TOKEN(Tokens[5], tok::plus, TT_OverloadedOperator); 9634986f3f2SEmilia Kond EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_OverloadedOperatorLParen); 9644986f3f2SEmilia Kond EXPECT_TOKEN(Tokens[8], tok::star, TT_PointerOrReference); 9654986f3f2SEmilia Kond 9663f3620e5SOwen Pan Tokens = annotate("class Foo {\n" 9673f3620e5SOwen Pan " int c = operator+(a * b);\n" 9683f3620e5SOwen Pan "}"); 9693f3620e5SOwen Pan ASSERT_EQ(Tokens.size(), 16u) << Tokens; 9703f3620e5SOwen Pan EXPECT_TOKEN(Tokens[6], tok::kw_operator, TT_Unknown); 9713f3620e5SOwen Pan EXPECT_TOKEN(Tokens[7], tok::plus, TT_OverloadedOperator); 9723f3620e5SOwen Pan EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_OverloadedOperatorLParen); 9733f3620e5SOwen Pan EXPECT_TOKEN(Tokens[10], tok::star, TT_BinaryOperator); 9743f3620e5SOwen Pan 9754986f3f2SEmilia Kond Tokens = annotate("void foo() {\n" 9764986f3f2SEmilia Kond " operator+(a * b);\n" 9774986f3f2SEmilia Kond "}"); 9784986f3f2SEmilia Kond ASSERT_EQ(Tokens.size(), 15u) << Tokens; 9793f3620e5SOwen Pan EXPECT_TOKEN(Tokens[5], tok::kw_operator, TT_Unknown); 9804986f3f2SEmilia Kond EXPECT_TOKEN(Tokens[6], tok::plus, TT_OverloadedOperator); 9814986f3f2SEmilia Kond EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_OverloadedOperatorLParen); 9824986f3f2SEmilia Kond EXPECT_TOKEN(Tokens[9], tok::star, TT_BinaryOperator); 9834986f3f2SEmilia Kond 9843f3620e5SOwen Pan Tokens = annotate("return operator+(a * b, c & d) + operator+(a && b && c);"); 9853f3620e5SOwen Pan ASSERT_EQ(Tokens.size(), 24u) << Tokens; 9863f3620e5SOwen Pan EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_Unknown); 9873f3620e5SOwen Pan EXPECT_TOKEN(Tokens[2], tok::plus, TT_OverloadedOperator); 9883f3620e5SOwen Pan EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperatorLParen); 9893f3620e5SOwen Pan EXPECT_TOKEN(Tokens[5], tok::star, TT_BinaryOperator); 9903f3620e5SOwen Pan EXPECT_TOKEN(Tokens[9], tok::amp, TT_BinaryOperator); 9913f3620e5SOwen Pan EXPECT_TOKEN(Tokens[13], tok::kw_operator, TT_Unknown); 9923f3620e5SOwen Pan EXPECT_TOKEN(Tokens[14], tok::plus, TT_OverloadedOperator); 9933f3620e5SOwen Pan EXPECT_TOKEN(Tokens[15], tok::l_paren, TT_OverloadedOperatorLParen); 9943f3620e5SOwen Pan EXPECT_TOKEN(Tokens[17], tok::ampamp, TT_BinaryOperator); 9953f3620e5SOwen Pan EXPECT_TOKEN(Tokens[19], tok::ampamp, TT_BinaryOperator); 9963f3620e5SOwen Pan 9974986f3f2SEmilia Kond Tokens = annotate("class Foo {\n" 9984986f3f2SEmilia Kond " void foo() {\n" 9994986f3f2SEmilia Kond " operator+(a * b);\n" 10004986f3f2SEmilia Kond " }\n" 10014986f3f2SEmilia Kond "}"); 10024986f3f2SEmilia Kond ASSERT_EQ(Tokens.size(), 19u) << Tokens; 10033f3620e5SOwen Pan EXPECT_TOKEN(Tokens[8], tok::kw_operator, TT_Unknown); 10044986f3f2SEmilia Kond EXPECT_TOKEN(Tokens[9], tok::plus, TT_OverloadedOperator); 10054986f3f2SEmilia Kond EXPECT_TOKEN(Tokens[10], tok::l_paren, TT_OverloadedOperatorLParen); 10064986f3f2SEmilia Kond EXPECT_TOKEN(Tokens[12], tok::star, TT_BinaryOperator); 1007cc2ff02eSOwen Pan 1008cc2ff02eSOwen Pan Tokens = annotate("std::vector<Foo> operator()(Foo &foo);"); 1009cc2ff02eSOwen Pan ASSERT_EQ(Tokens.size(), 16u) << Tokens; 1010cc2ff02eSOwen Pan EXPECT_TOKEN(Tokens[3], tok::less, TT_TemplateOpener); 1011cc2ff02eSOwen Pan EXPECT_TOKEN(Tokens[5], tok::greater, TT_TemplateCloser); 1012cc2ff02eSOwen Pan EXPECT_TOKEN(Tokens[6], tok::kw_operator, TT_FunctionDeclarationName); 1013cc2ff02eSOwen Pan EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_OverloadedOperator); 1014cc2ff02eSOwen Pan EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_OverloadedOperator); 1015cc2ff02eSOwen Pan EXPECT_TOKEN(Tokens[9], tok::l_paren, TT_OverloadedOperatorLParen); 1016cc2ff02eSOwen Pan EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference); 101767b99fa8SOwen Pan 101867b99fa8SOwen Pan Tokens = annotate("decltype(auto) operator()(T &x);"); 101967b99fa8SOwen Pan ASSERT_EQ(Tokens.size(), 14u) << Tokens; 102067b99fa8SOwen Pan EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_TypeDeclarationParen); 102167b99fa8SOwen Pan EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_TypeDeclarationParen); 102267b99fa8SOwen Pan EXPECT_TOKEN(Tokens[4], tok::kw_operator, TT_FunctionDeclarationName); 102367b99fa8SOwen Pan EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperator); 102467b99fa8SOwen Pan EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_OverloadedOperator); 102567b99fa8SOwen Pan EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_OverloadedOperatorLParen); 102667b99fa8SOwen Pan EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference); 1027b5f6689dSOwen Pan 1028b5f6689dSOwen Pan Tokens = annotate("friend ostream& ::operator<<(ostream& lhs, foo& rhs);"); 1029b5f6689dSOwen Pan ASSERT_EQ(Tokens.size(), 17u) << Tokens; 1030b5f6689dSOwen Pan EXPECT_TOKEN(Tokens[4], tok::kw_operator, TT_FunctionDeclarationName); 1031b5f6689dSOwen Pan EXPECT_TOKEN(Tokens[5], tok::lessless, TT_OverloadedOperator); 1032b5f6689dSOwen Pan EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_OverloadedOperatorLParen); 1033b5f6689dSOwen Pan EXPECT_TOKEN(Tokens[8], tok::amp, TT_PointerOrReference); 1034b5f6689dSOwen Pan EXPECT_TOKEN(Tokens[12], tok::amp, TT_PointerOrReference); 10358e31050bSOwen Pan 10368e31050bSOwen Pan Tokens = annotate("SomeLoooooooooooooooooType::Awaitable\n" 10378e31050bSOwen Pan "SomeLoooooooooooooooooType::operator co_await();"); 10388e31050bSOwen Pan ASSERT_EQ(Tokens.size(), 11u) << Tokens; 10398e31050bSOwen Pan EXPECT_TOKEN(Tokens[3], tok::identifier, TT_FunctionDeclarationName); 10408e31050bSOwen Pan EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_OverloadedOperatorLParen); 1041dce5bb9aSEmilia Dreamer } 1042dce5bb9aSEmilia Dreamer 1043682808d9SOwen Pan TEST_F(TokenAnnotatorTest, OverloadedOperatorInTemplate) { 1044682808d9SOwen Pan struct { 1045682808d9SOwen Pan const char *Text; 1046682808d9SOwen Pan tok::TokenKind Kind; 1047682808d9SOwen Pan } Operators[] = {{"+", tok::plus}, 1048682808d9SOwen Pan {"-", tok::minus}, 1049682808d9SOwen Pan // FIXME: 1050682808d9SOwen Pan // {"*", tok::star}, 1051682808d9SOwen Pan {"/", tok::slash}, 1052682808d9SOwen Pan {"%", tok::percent}, 1053682808d9SOwen Pan {"^", tok::caret}, 1054682808d9SOwen Pan // FIXME: 1055682808d9SOwen Pan // {"&", tok::amp}, 1056682808d9SOwen Pan {"|", tok::pipe}, 1057682808d9SOwen Pan {"~", tok::tilde}, 1058682808d9SOwen Pan {"!", tok::exclaim}, 1059682808d9SOwen Pan {"=", tok::equal}, 1060682808d9SOwen Pan // FIXME: 1061682808d9SOwen Pan // {"<", tok::less}, 1062682808d9SOwen Pan {">", tok::greater}, 1063682808d9SOwen Pan {"+=", tok::plusequal}, 1064682808d9SOwen Pan {"-=", tok::minusequal}, 1065682808d9SOwen Pan {"*=", tok::starequal}, 1066682808d9SOwen Pan {"/=", tok::slashequal}, 1067682808d9SOwen Pan {"%=", tok::percentequal}, 1068682808d9SOwen Pan {"^=", tok::caretequal}, 1069682808d9SOwen Pan {"&=", tok::ampequal}, 1070682808d9SOwen Pan {"|=", tok::pipeequal}, 1071682808d9SOwen Pan {"<<", tok::lessless}, 1072682808d9SOwen Pan {">>", tok::greatergreater}, 1073682808d9SOwen Pan {">>=", tok::greatergreaterequal}, 1074682808d9SOwen Pan {"<<=", tok::lesslessequal}, 1075682808d9SOwen Pan {"==", tok::equalequal}, 1076682808d9SOwen Pan {"!=", tok::exclaimequal}, 1077682808d9SOwen Pan {"<=", tok::lessequal}, 1078682808d9SOwen Pan {">=", tok::greaterequal}, 1079682808d9SOwen Pan {"<=>", tok::spaceship}, 1080682808d9SOwen Pan {"&&", tok::ampamp}, 1081682808d9SOwen Pan {"||", tok::pipepipe}, 1082682808d9SOwen Pan {"++", tok::plusplus}, 1083682808d9SOwen Pan {"--", tok::minusminus}, 1084682808d9SOwen Pan {",", tok::comma}, 1085682808d9SOwen Pan {"->*", tok::arrowstar}, 1086682808d9SOwen Pan {"->", tok::arrow}}; 1087682808d9SOwen Pan 1088682808d9SOwen Pan for (const auto &Operator : Operators) { 1089682808d9SOwen Pan std::string Input("C<&operator"); 1090682808d9SOwen Pan Input += Operator.Text; 1091682808d9SOwen Pan Input += " > a;"; 1092682808d9SOwen Pan auto Tokens = annotate(std::string(Input)); 1093682808d9SOwen Pan ASSERT_EQ(Tokens.size(), 9u) << Tokens; 1094682808d9SOwen Pan EXPECT_TOKEN(Tokens[1], tok::less, TT_TemplateOpener); 1095682808d9SOwen Pan EXPECT_TOKEN(Tokens[4], Operator.Kind, TT_OverloadedOperator); 1096682808d9SOwen Pan EXPECT_TOKEN(Tokens[5], tok::greater, TT_TemplateCloser); 1097682808d9SOwen Pan } 1098682808d9SOwen Pan 1099682808d9SOwen Pan auto Tokens = annotate("C<&operator< <X>> lt;"); 1100682808d9SOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 1101682808d9SOwen Pan EXPECT_TOKEN(Tokens[1], tok::less, TT_TemplateOpener); 1102682808d9SOwen Pan EXPECT_TOKEN(Tokens[4], tok::less, TT_OverloadedOperator); 1103682808d9SOwen Pan EXPECT_TOKEN(Tokens[5], tok::less, TT_TemplateOpener); 1104682808d9SOwen Pan EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser); 1105682808d9SOwen Pan EXPECT_TOKEN(Tokens[8], tok::greater, TT_TemplateCloser); 1106682808d9SOwen Pan } 1107682808d9SOwen Pan 11089aab0db1SBjörn Schäpers TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) { 11099aab0db1SBjörn Schäpers auto Tokens = annotate("template <typename T>\n" 11109aab0db1SBjörn Schäpers "concept C = (Foo && Bar) && (Bar && Baz);"); 11119aab0db1SBjörn Schäpers 11129aab0db1SBjörn Schäpers ASSERT_EQ(Tokens.size(), 21u) << Tokens; 11139aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_BinaryOperator); 11149aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_BinaryOperator); 11159aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[16], tok::ampamp, TT_BinaryOperator); 11169aab0db1SBjörn Schäpers 11179aab0db1SBjörn Schäpers Tokens = annotate("template <typename T>\n" 1118bd3dd10aSEmilia Dreamer "concept C = Foo && !Bar;"); 1119bd3dd10aSEmilia Dreamer 1120bd3dd10aSEmilia Dreamer ASSERT_EQ(Tokens.size(), 14u) << Tokens; 1121bd3dd10aSEmilia Dreamer EXPECT_TOKEN(Tokens[9], tok::ampamp, TT_BinaryOperator); 1122bd3dd10aSEmilia Dreamer EXPECT_TOKEN(Tokens[10], tok::exclaim, TT_UnaryOperator); 1123bd3dd10aSEmilia Dreamer 1124bd3dd10aSEmilia Dreamer Tokens = annotate("template <typename T>\n" 11259aab0db1SBjörn Schäpers "concept C = requires(T t) {\n" 11269aab0db1SBjörn Schäpers " { t.foo() };\n" 11279aab0db1SBjörn Schäpers "} && Bar<T> && Baz<T>;"); 11289aab0db1SBjörn Schäpers ASSERT_EQ(Tokens.size(), 35u) << Tokens; 1129bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[8], tok::kw_requires, TT_RequiresExpression); 1130bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[9], tok::l_paren, TT_RequiresExpressionLParen); 1131bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_RequiresExpressionLBrace); 11329aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[23], tok::ampamp, TT_BinaryOperator); 11339aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[28], tok::ampamp, TT_BinaryOperator); 11349aab0db1SBjörn Schäpers 11359aab0db1SBjörn Schäpers Tokens = annotate("template<typename T>\n" 11369aab0db1SBjörn Schäpers "requires C1<T> && (C21<T> || C22<T> && C2e<T>) && C3<T>\n" 11379aab0db1SBjörn Schäpers "struct Foo;"); 11389aab0db1SBjörn Schäpers ASSERT_EQ(Tokens.size(), 36u) << Tokens; 1139bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); 11409aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[6], tok::identifier, TT_Unknown); 11419aab0db1SBjörn Schäpers EXPECT_EQ(Tokens[6]->FakeLParens.size(), 1u); 11429aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_BinaryOperator); 11439aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[16], tok::pipepipe, TT_BinaryOperator); 11449aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[21], tok::ampamp, TT_BinaryOperator); 11459aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[27], tok::ampamp, TT_BinaryOperator); 11469aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[31], tok::greater, TT_TemplateCloser); 11479aab0db1SBjörn Schäpers EXPECT_EQ(Tokens[31]->FakeRParens, 1u); 11489aab0db1SBjörn Schäpers EXPECT_TRUE(Tokens[31]->ClosesRequiresClause); 11499aab0db1SBjörn Schäpers 11509aab0db1SBjörn Schäpers Tokens = 11519aab0db1SBjörn Schäpers annotate("template<typename T>\n" 11529aab0db1SBjörn Schäpers "requires (C1<T> && (C21<T> || C22<T> && C2e<T>) && C3<T>)\n" 11539aab0db1SBjörn Schäpers "struct Foo;"); 11549aab0db1SBjörn Schäpers ASSERT_EQ(Tokens.size(), 38u) << Tokens; 1155bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); 11569aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[7], tok::identifier, TT_Unknown); 11579aab0db1SBjörn Schäpers EXPECT_EQ(Tokens[7]->FakeLParens.size(), 1u); 11589aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[11], tok::ampamp, TT_BinaryOperator); 11599aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[17], tok::pipepipe, TT_BinaryOperator); 11609aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[22], tok::ampamp, TT_BinaryOperator); 11619aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[28], tok::ampamp, TT_BinaryOperator); 11629aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[32], tok::greater, TT_TemplateCloser); 11639aab0db1SBjörn Schäpers EXPECT_EQ(Tokens[32]->FakeRParens, 1u); 11649aab0db1SBjörn Schäpers EXPECT_TOKEN(Tokens[33], tok::r_paren, TT_Unknown); 11659aab0db1SBjörn Schäpers EXPECT_TRUE(Tokens[33]->ClosesRequiresClause); 1166bcd1e461SBjörn Schäpers 1167bcd1e461SBjörn Schäpers Tokens = annotate("template <typename T>\n" 1168bcd1e461SBjörn Schäpers "void foo(T) noexcept requires Bar<T>;"); 1169bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 18u) << Tokens; 1170bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause); 1171bcd1e461SBjörn Schäpers 1172bcd1e461SBjörn Schäpers Tokens = annotate("template <typename T>\n" 11730bf63f0dSEmilia Dreamer "requires Bar<T> || Baz<T>\n" 11740bf63f0dSEmilia Dreamer "auto foo(T) -> int;"); 11750bf63f0dSEmilia Dreamer ASSERT_EQ(Tokens.size(), 24u) << Tokens; 11760bf63f0dSEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); 11770bf63f0dSEmilia Dreamer EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u); 11780bf63f0dSEmilia Dreamer EXPECT_TRUE(Tokens[14]->ClosesRequiresClause); 11790bf63f0dSEmilia Dreamer EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow); 11800bf63f0dSEmilia Dreamer 11810bf63f0dSEmilia Dreamer Tokens = annotate("template <typename T>\n" 118239e6077dSEmilia Dreamer "requires Bar<T>\n" 118339e6077dSEmilia Dreamer "bool foo(T) { return false; }"); 118439e6077dSEmilia Dreamer ASSERT_EQ(Tokens.size(), 21u) << Tokens; 118539e6077dSEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); 118639e6077dSEmilia Dreamer EXPECT_TRUE(Tokens[9]->ClosesRequiresClause); 118739e6077dSEmilia Dreamer EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName); 1188b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[12], tok::l_paren, TT_FunctionDeclarationLParen); 118939e6077dSEmilia Dreamer 119039e6077dSEmilia Dreamer Tokens = annotate("template <typename T>\n" 1191d9899501SEmilia Dreamer "requires Bar<T>\n" 1192d9899501SEmilia Dreamer "decltype(auto) foo(T) { return false; }"); 1193d9899501SEmilia Dreamer ASSERT_EQ(Tokens.size(), 24u) << Tokens; 1194d9899501SEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); 1195d9899501SEmilia Dreamer EXPECT_TRUE(Tokens[9]->ClosesRequiresClause); 1196d9899501SEmilia Dreamer EXPECT_TOKEN(Tokens[14], tok::identifier, TT_FunctionDeclarationName); 1197b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[15], tok::l_paren, TT_FunctionDeclarationLParen); 1198d9899501SEmilia Dreamer 1199d9899501SEmilia Dreamer Tokens = annotate("template <typename T>\n" 1200bcd1e461SBjörn Schäpers "struct S {\n" 1201bcd1e461SBjörn Schäpers " void foo() const requires Bar<T>;\n" 1202bcd1e461SBjörn Schäpers " void bar() const & requires Baz<T>;\n" 1203bcd1e461SBjörn Schäpers " void bar() && requires Baz2<T>;\n" 1204bcd1e461SBjörn Schäpers " void baz() const & noexcept requires Baz<T>;\n" 1205bcd1e461SBjörn Schäpers " void baz() && noexcept requires Baz2<T>;\n" 1206bcd1e461SBjörn Schäpers "};\n" 1207bcd1e461SBjörn Schäpers "\n" 1208bcd1e461SBjörn Schäpers "void S::bar() const & requires Baz<T> { }"); 1209bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 85u) << Tokens; 1210bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[13], tok::kw_requires, TT_RequiresClause); 1211c9163901SEmilia Dreamer EXPECT_TOKEN(Tokens[24], tok::amp, TT_PointerOrReference); 1212bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[25], tok::kw_requires, TT_RequiresClause); 1213c9163901SEmilia Dreamer EXPECT_TOKEN(Tokens[35], tok::ampamp, TT_PointerOrReference); 1214bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[36], tok::kw_requires, TT_RequiresClause); 1215c9163901SEmilia Dreamer EXPECT_TOKEN(Tokens[47], tok::amp, TT_PointerOrReference); 1216bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[49], tok::kw_requires, TT_RequiresClause); 1217c9163901SEmilia Dreamer EXPECT_TOKEN(Tokens[59], tok::ampamp, TT_PointerOrReference); 1218bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[61], tok::kw_requires, TT_RequiresClause); 1219c9163901SEmilia Dreamer EXPECT_TOKEN(Tokens[76], tok::amp, TT_PointerOrReference); 1220bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[77], tok::kw_requires, TT_RequiresClause); 1221bcd1e461SBjörn Schäpers 1222bcd1e461SBjörn Schäpers Tokens = annotate("void Class::member() && requires(Constant) {}"); 1223bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 14u) << Tokens; 1224bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[7], tok::kw_requires, TT_RequiresClause); 1225bcd1e461SBjörn Schäpers 1226bcd1e461SBjörn Schäpers Tokens = annotate("void Class::member() && requires(Constant<T>) {}"); 1227bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 17u) << Tokens; 1228bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[7], tok::kw_requires, TT_RequiresClause); 1229bcd1e461SBjörn Schäpers 1230bcd1e461SBjörn Schäpers Tokens = 1231bcd1e461SBjörn Schäpers annotate("void Class::member() && requires(Namespace::Constant<T>) {}"); 1232bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 19u) << Tokens; 1233bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[7], tok::kw_requires, TT_RequiresClause); 1234bcd1e461SBjörn Schäpers 1235bcd1e461SBjörn Schäpers Tokens = annotate("void Class::member() && requires(typename " 1236bcd1e461SBjörn Schäpers "Namespace::Outer<T>::Inner::Constant) {}"); 1237bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 24u) << Tokens; 1238bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[7], tok::kw_requires, TT_RequiresClause); 1239be9a7fddSBjörn Schäpers 1240be9a7fddSBjörn Schäpers Tokens = annotate("struct [[nodiscard]] zero_t {\n" 1241be9a7fddSBjörn Schäpers " template<class T>\n" 1242be9a7fddSBjörn Schäpers " requires requires { number_zero_v<T>; }\n" 1243be9a7fddSBjörn Schäpers " [[nodiscard]] constexpr operator T() const { " 1244be9a7fddSBjörn Schäpers "return number_zero_v<T>; }\n" 1245be9a7fddSBjörn Schäpers "};"); 1246b6301a01Ssstwcw ASSERT_EQ(Tokens.size(), 44u) << Tokens; 1247be9a7fddSBjörn Schäpers EXPECT_TOKEN(Tokens[13], tok::kw_requires, TT_RequiresClause); 1248be9a7fddSBjörn Schäpers EXPECT_TOKEN(Tokens[14], tok::kw_requires, TT_RequiresExpression); 1249be9a7fddSBjörn Schäpers EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_RequiresExpressionLBrace); 1250be9a7fddSBjörn Schäpers EXPECT_TOKEN(Tokens[21], tok::r_brace, TT_Unknown); 1251be9a7fddSBjörn Schäpers EXPECT_EQ(Tokens[21]->MatchingParen, Tokens[15]); 1252be9a7fddSBjörn Schäpers EXPECT_TRUE(Tokens[21]->ClosesRequiresClause); 1253dab5e10eSSergey Semushin 1254dab5e10eSSergey Semushin Tokens = 1255dab5e10eSSergey Semushin annotate("template <class A, class B> concept C =" 1256dab5e10eSSergey Semushin "std::same_as<std::iter_value_t<A>, std::iter_value_t<B>>;"); 1257dab5e10eSSergey Semushin ASSERT_EQ(Tokens.size(), 31u) << Tokens; 1258dab5e10eSSergey Semushin EXPECT_TOKEN(Tokens[8], tok::kw_concept, TT_Unknown); 1259dab5e10eSSergey Semushin EXPECT_TOKEN(Tokens[14], tok::less, TT_TemplateOpener); 1260dab5e10eSSergey Semushin EXPECT_TOKEN(Tokens[18], tok::less, TT_TemplateOpener); 1261dab5e10eSSergey Semushin EXPECT_TOKEN(Tokens[20], tok::greater, TT_TemplateCloser); 1262dab5e10eSSergey Semushin EXPECT_TOKEN(Tokens[25], tok::less, TT_TemplateOpener); 1263dab5e10eSSergey Semushin EXPECT_TOKEN(Tokens[27], tok::greater, TT_TemplateCloser); 1264dab5e10eSSergey Semushin EXPECT_TOKEN(Tokens[28], tok::greater, TT_TemplateCloser); 1265b3aeca39SBjörn Schäpers 1266b3aeca39SBjörn Schäpers Tokens = annotate("auto bar() -> int requires(is_integral_v<T>) {}"); 1267b3aeca39SBjörn Schäpers ASSERT_EQ(Tokens.size(), 16u) << Tokens; 1268b3aeca39SBjörn Schäpers EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 1269b3aeca39SBjörn Schäpers 1270b3aeca39SBjörn Schäpers Tokens = annotate("auto bar() -> void requires(is_integral_v<T>) {}"); 1271b3aeca39SBjörn Schäpers ASSERT_EQ(Tokens.size(), 16u) << Tokens; 1272b3aeca39SBjörn Schäpers EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 1273b3aeca39SBjörn Schäpers 1274b3aeca39SBjörn Schäpers Tokens = annotate("auto bar() -> MyType requires(is_integral_v<T>) {}"); 1275b3aeca39SBjörn Schäpers ASSERT_EQ(Tokens.size(), 16u) << Tokens; 1276b3aeca39SBjörn Schäpers EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 1277b3aeca39SBjörn Schäpers 1278b3aeca39SBjörn Schäpers Tokens = 1279b3aeca39SBjörn Schäpers annotate("auto bar() -> SOME_MACRO_TYPE requires(is_integral_v<T>) {}"); 1280b3aeca39SBjörn Schäpers ASSERT_EQ(Tokens.size(), 16u) << Tokens; 1281b3aeca39SBjörn Schäpers EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 1282b3aeca39SBjörn Schäpers 1283b3aeca39SBjörn Schäpers Tokens = 1284b3aeca39SBjörn Schäpers annotate("auto bar() -> qualified::type requires(is_integral_v<T>) {}"); 1285b3aeca39SBjörn Schäpers ASSERT_EQ(Tokens.size(), 18u) << Tokens; 1286b3aeca39SBjörn Schäpers EXPECT_TOKEN(Tokens[8], tok::kw_requires, TT_RequiresClause); 1287b3aeca39SBjörn Schäpers 1288b3aeca39SBjörn Schäpers Tokens = 1289b3aeca39SBjörn Schäpers annotate("auto bar() -> Template<type> requires(is_integral_v<T>) {}"); 1290b3aeca39SBjörn Schäpers ASSERT_EQ(Tokens.size(), 19u) << Tokens; 1291b3aeca39SBjörn Schäpers EXPECT_TOKEN(Tokens[9], tok::kw_requires, TT_RequiresClause); 129215e14f12SEmilia Kond 129315e14f12SEmilia Kond Tokens = annotate("void foo() requires((A<T>) && C) {}"); 129415e14f12SEmilia Kond ASSERT_EQ(Tokens.size(), 18u) << Tokens; 129515e14f12SEmilia Kond EXPECT_TOKEN(Tokens[4], tok::kw_requires, TT_RequiresClause); 129615e14f12SEmilia Kond EXPECT_TOKEN(Tokens[12], tok::ampamp, TT_BinaryOperator); 129715e14f12SEmilia Kond 129815e14f12SEmilia Kond Tokens = annotate("void foo() requires(((A<T>) && C)) {}"); 129915e14f12SEmilia Kond ASSERT_EQ(Tokens.size(), 20u) << Tokens; 130015e14f12SEmilia Kond EXPECT_TOKEN(Tokens[4], tok::kw_requires, TT_RequiresClause); 130115e14f12SEmilia Kond EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_BinaryOperator); 130215e14f12SEmilia Kond 130315e14f12SEmilia Kond Tokens = annotate("void foo() requires([](T&&){}(t)) {}"); 130415e14f12SEmilia Kond ASSERT_EQ(Tokens.size(), 21u) << Tokens; 130515e14f12SEmilia Kond EXPECT_TOKEN(Tokens[4], tok::kw_requires, TT_RequiresClause); 130615e14f12SEmilia Kond EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_PointerOrReference); 130715e14f12SEmilia Kond 130815e14f12SEmilia Kond Tokens = annotate("void foo() requires([](T&& u){}(t)) {}"); 130915e14f12SEmilia Kond ASSERT_EQ(Tokens.size(), 22u) << Tokens; 131015e14f12SEmilia Kond EXPECT_TOKEN(Tokens[4], tok::kw_requires, TT_RequiresClause); 131115e14f12SEmilia Kond EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_PointerOrReference); 13123e87829aSEmilia Kond 13133e87829aSEmilia Kond Tokens = annotate("void f() & requires(true) {}"); 131488d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 12u) << Tokens; 13153e87829aSEmilia Kond EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference); 13163e87829aSEmilia Kond EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); 13173e87829aSEmilia Kond 13183e87829aSEmilia Kond Tokens = annotate("void f() & requires(C<true, true>) {}"); 131988d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 17u) << Tokens; 13203e87829aSEmilia Kond EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference); 13213e87829aSEmilia Kond EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); 1322791637e7SEmilia Kond 1323791637e7SEmilia Kond Tokens = annotate("template <typename T>\n" 1324791637e7SEmilia Kond "concept C = (!Foo<T>) && Bar;"); 1325791637e7SEmilia Kond ASSERT_EQ(Tokens.size(), 19u) << Tokens; 1326791637e7SEmilia Kond EXPECT_TOKEN(Tokens[15], tok::ampamp, TT_BinaryOperator); 13279b68c095SEmilia Kond 13289b68c095SEmilia Kond Tokens = annotate("void f() & requires(C<decltype(x)>) {}"); 13299b68c095SEmilia Kond ASSERT_EQ(Tokens.size(), 18u) << Tokens; 13309b68c095SEmilia Kond EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference); 13319b68c095SEmilia Kond EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); 13329b68c095SEmilia Kond 13339b68c095SEmilia Kond Tokens = annotate("auto f() -> int& requires(C<decltype(x)>) {}"); 13349b68c095SEmilia Kond ASSERT_EQ(Tokens.size(), 20u) << Tokens; 13359b68c095SEmilia Kond EXPECT_TOKEN(Tokens[6], tok::amp, TT_PointerOrReference); 13369b68c095SEmilia Kond EXPECT_TOKEN(Tokens[7], tok::kw_requires, TT_RequiresClause); 13379b68c095SEmilia Kond 13389b68c095SEmilia Kond Tokens = annotate("bool x = t && requires(decltype(t) x) { x.foo(); };"); 13399b68c095SEmilia Kond ASSERT_EQ(Tokens.size(), 23u) << Tokens; 13409b68c095SEmilia Kond EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresExpression); 13419b68c095SEmilia Kond 13429b68c095SEmilia Kond Tokens = annotate("bool x = t && requires(Foo<decltype(t)> x) { x.foo(); };"); 13439b68c095SEmilia Kond ASSERT_EQ(Tokens.size(), 26u) << Tokens; 13449b68c095SEmilia Kond EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresExpression); 13459b68c095SEmilia Kond 13469b68c095SEmilia Kond Tokens = annotate("bool x = t && requires(Foo<C1 || C2> x) { x.foo(); };"); 13479b68c095SEmilia Kond ASSERT_EQ(Tokens.size(), 25u) << Tokens; 13489b68c095SEmilia Kond EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresExpression); 1349aea60ab9SEmilia Kond 1350aea60ab9SEmilia Kond // Second function definition is required due to lookahead 1351aea60ab9SEmilia Kond Tokens = annotate("void f() &\n" 1352aea60ab9SEmilia Kond " requires(n == 1)\n" 1353aea60ab9SEmilia Kond "{}\n" 1354aea60ab9SEmilia Kond "void g();"); 1355aea60ab9SEmilia Kond ASSERT_EQ(Tokens.size(), 19u) << Tokens; 1356aea60ab9SEmilia Kond EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference); 1357aea60ab9SEmilia Kond EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); 1358bcd1e461SBjörn Schäpers } 1359bcd1e461SBjörn Schäpers 1360bcd1e461SBjörn Schäpers TEST_F(TokenAnnotatorTest, UnderstandsRequiresExpressions) { 1361bcd1e461SBjörn Schäpers auto Tokens = annotate("bool b = requires(int i) { i + 5; };"); 1362bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 16u) << Tokens; 1363bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression); 1364bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen); 1365bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); 1366bcd1e461SBjörn Schäpers 1367bcd1e461SBjörn Schäpers Tokens = annotate("if (requires(int i) { i + 5; }) return;"); 1368bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 17u) << Tokens; 1369bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); 1370bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); 1371bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_RequiresExpressionLBrace); 1372bcd1e461SBjörn Schäpers 1373bcd1e461SBjörn Schäpers Tokens = annotate("if (func() && requires(int i) { i + 5; }) return;"); 1374bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 21u) << Tokens; 1375bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresExpression); 1376bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_RequiresExpressionLParen); 1377bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_RequiresExpressionLBrace); 1378bcd1e461SBjörn Schäpers 1379bcd1e461SBjörn Schäpers Tokens = annotate("foo(requires(const T t) {});"); 1380bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 13u) << Tokens; 1381bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); 1382bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); 1383bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); 1384bcd1e461SBjörn Schäpers 1385bcd1e461SBjörn Schäpers Tokens = annotate("foo(requires(const int t) {});"); 1386bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 13u) << Tokens; 1387bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); 1388bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); 1389bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); 1390bcd1e461SBjörn Schäpers 1391bcd1e461SBjörn Schäpers Tokens = annotate("foo(requires(const T t) {});"); 1392bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 13u) << Tokens; 1393bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); 1394bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); 1395bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); 1396bcd1e461SBjörn Schäpers 1397bcd1e461SBjörn Schäpers Tokens = annotate("foo(requires(int const* volatile t) {});"); 1398bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 15u) << Tokens; 1399bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); 1400bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); 14010ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference); 1402bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace); 1403bcd1e461SBjörn Schäpers 1404bcd1e461SBjörn Schäpers Tokens = annotate("foo(requires(T const* volatile t) {});"); 1405bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 15u) << Tokens; 1406bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); 1407bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); 14080ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference); 1409bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace); 1410bcd1e461SBjörn Schäpers 14110ebed862SEmilia Dreamer Tokens = annotate("foo(requires(T& t) {});"); 14120ebed862SEmilia Dreamer ASSERT_EQ(Tokens.size(), 13u) << Tokens; 14130ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); 14140ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); 14150ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::amp, TT_PointerOrReference); 14160ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); 14170ebed862SEmilia Dreamer 14180ebed862SEmilia Dreamer Tokens = annotate("foo(requires(T&& t) {});"); 14190ebed862SEmilia Dreamer ASSERT_EQ(Tokens.size(), 13u) << Tokens; 14200ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); 14210ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); 14220ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::ampamp, TT_PointerOrReference); 14230ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); 14240ebed862SEmilia Dreamer 14250ebed862SEmilia Dreamer Tokens = annotate("bool foo = requires(T& t) {};"); 14260ebed862SEmilia Dreamer ASSERT_EQ(Tokens.size(), 13u) << Tokens; 14270ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression); 14280ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen); 14290ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::amp, TT_PointerOrReference); 14300ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_RequiresExpressionLBrace); 14310ebed862SEmilia Dreamer 14320ebed862SEmilia Dreamer Tokens = annotate("bool foo = requires(T&& t) {};"); 14330ebed862SEmilia Dreamer ASSERT_EQ(Tokens.size(), 13u) << Tokens; 14340ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression); 14350ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen); 14360ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::ampamp, TT_PointerOrReference); 14370ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_RequiresExpressionLBrace); 14380ebed862SEmilia Dreamer 1439bcd1e461SBjörn Schäpers Tokens = 1440bcd1e461SBjörn Schäpers annotate("foo(requires(const typename Outer<T>::Inner * const t) {});"); 1441bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 21u) << Tokens; 1442bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); 1443bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); 14440ebed862SEmilia Dreamer EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference); 1445bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[16], tok::l_brace, TT_RequiresExpressionLBrace); 1446bcd1e461SBjörn Schäpers 1447bcd1e461SBjörn Schäpers Tokens = annotate("template <typename T>\n" 1448bcd1e461SBjörn Schäpers "concept C = requires(T T) {\n" 1449bcd1e461SBjörn Schäpers " requires Bar<T> && Foo<T>;\n" 1450bcd1e461SBjörn Schäpers "};"); 1451bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 28u) << Tokens; 1452bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[8], tok::kw_requires, TT_RequiresExpression); 1453bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[9], tok::l_paren, TT_RequiresExpressionLParen); 1454bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_RequiresExpressionLBrace); 1455bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[14], tok::kw_requires, 1456bcd1e461SBjörn Schäpers TT_RequiresClauseInARequiresExpression); 1457bcd1e461SBjörn Schäpers 1458bcd1e461SBjörn Schäpers Tokens = annotate("template <typename T>\n" 1459bcd1e461SBjörn Schäpers "concept C = requires(T T) {\n" 1460bcd1e461SBjörn Schäpers " { t.func() } -> std::same_as<int>;" 1461bcd1e461SBjörn Schäpers " requires Bar<T> && Foo<T>;\n" 1462bcd1e461SBjörn Schäpers "};"); 1463bcd1e461SBjörn Schäpers ASSERT_EQ(Tokens.size(), 43u) << Tokens; 1464bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[8], tok::kw_requires, TT_RequiresExpression); 1465bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[9], tok::l_paren, TT_RequiresExpressionLParen); 1466bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_RequiresExpressionLBrace); 1467bcd1e461SBjörn Schäpers EXPECT_TOKEN(Tokens[29], tok::kw_requires, 1468bcd1e461SBjörn Schäpers TT_RequiresClauseInARequiresExpression); 1469acd17a2bSBjörn Schäpers 1470acd17a2bSBjörn Schäpers // Invalid Code, but we don't want to crash. See http://llvm.org/PR54350. 1471acd17a2bSBjörn Schäpers Tokens = annotate("bool r10 = requires (struct new_struct { int x; } s) { " 1472acd17a2bSBjörn Schäpers "requires true; };"); 1473acd17a2bSBjörn Schäpers ASSERT_EQ(Tokens.size(), 21u) << Tokens; 1474acd17a2bSBjörn Schäpers EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression); 1475acd17a2bSBjörn Schäpers EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen); 1476acd17a2bSBjörn Schäpers EXPECT_TOKEN(Tokens[14], tok::l_brace, TT_RequiresExpressionLBrace); 14773e87829aSEmilia Kond 14783e87829aSEmilia Kond Tokens = annotate("bool foo = requires(C<true, true> c) {\n" 14793e87829aSEmilia Kond " { c.foo(); }\n" 14803e87829aSEmilia Kond "};"); 14813e87829aSEmilia Kond ASSERT_EQ(Tokens.size(), 25u) << Tokens; 14823e87829aSEmilia Kond EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression); 14833e87829aSEmilia Kond EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen); 14843e87829aSEmilia Kond EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_RequiresExpressionLBrace); 14859aab0db1SBjörn Schäpers } 14869aab0db1SBjörn Schäpers 1487fd1d93dbSTobias Hieta TEST_F(TokenAnnotatorTest, UnderstandsPragmaRegion) { 1488fd1d93dbSTobias Hieta // Everything after #pragma region should be ImplicitStringLiteral 1489fd1d93dbSTobias Hieta auto Tokens = annotate("#pragma region Foo(Bar: Hello)"); 1490fd1d93dbSTobias Hieta ASSERT_EQ(Tokens.size(), 10u) << Tokens; 1491fd1d93dbSTobias Hieta EXPECT_TOKEN(Tokens[5], tok::identifier, TT_ImplicitStringLiteral); 1492fd1d93dbSTobias Hieta EXPECT_TOKEN(Tokens[6], tok::colon, TT_ImplicitStringLiteral); 1493fd1d93dbSTobias Hieta EXPECT_TOKEN(Tokens[7], tok::identifier, TT_ImplicitStringLiteral); 1494fd1d93dbSTobias Hieta 1495fd1d93dbSTobias Hieta // Make sure it's annotated correctly inside a function as well 1496fd1d93dbSTobias Hieta Tokens = annotate("void test(){\n#pragma region Foo(Bar: Hello)\n}"); 1497fd1d93dbSTobias Hieta ASSERT_EQ(Tokens.size(), 16u) << Tokens; 1498fd1d93dbSTobias Hieta EXPECT_TOKEN(Tokens[10], tok::identifier, TT_ImplicitStringLiteral); 1499fd1d93dbSTobias Hieta EXPECT_TOKEN(Tokens[11], tok::colon, TT_ImplicitStringLiteral); 1500fd1d93dbSTobias Hieta EXPECT_TOKEN(Tokens[12], tok::identifier, TT_ImplicitStringLiteral); 1501fd1d93dbSTobias Hieta } 1502fd1d93dbSTobias Hieta 15039aab0db1SBjörn Schäpers TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { 1504a4c62f66Sowenca const char *BaseCode = nullptr; 1505a4c62f66Sowenca const char *ConstrainedCode = nullptr; 1506a4c62f66Sowenca auto BaseTokenCount = 0u; 1507a4c62f66Sowenca auto RequiresTokenCount = 0u; 1508a4c62f66Sowenca auto PrefixTokenCount = 0u; 15099aab0db1SBjörn Schäpers 1510a4c62f66Sowenca auto TestRequires = [&](int Line) { 1511a4c62f66Sowenca const auto BaseTokens = annotate(BaseCode); 1512a4c62f66Sowenca const auto ConstrainedTokens = annotate(ConstrainedCode); 1513a4c62f66Sowenca 1514a4c62f66Sowenca #define LINE " (Line " << Line << ')' 1515a4c62f66Sowenca 1516a4c62f66Sowenca ASSERT_EQ(BaseTokens.size(), BaseTokenCount) << BaseTokens << LINE; 1517a4c62f66Sowenca ASSERT_EQ(ConstrainedTokens.size(), BaseTokenCount + RequiresTokenCount) 1518a4c62f66Sowenca << LINE; 1519a4c62f66Sowenca 1520a4c62f66Sowenca for (auto I = 0u; I < BaseTokenCount; ++I) { 1521a4c62f66Sowenca EXPECT_EQ( 1522a4c62f66Sowenca *BaseTokens[I], 1523a4c62f66Sowenca *ConstrainedTokens[I < PrefixTokenCount ? I : I + RequiresTokenCount]) 1524a4c62f66Sowenca << I << LINE; 1525a4c62f66Sowenca } 1526a4c62f66Sowenca 1527a4c62f66Sowenca #undef LINE 1528a4c62f66Sowenca }; 1529a4c62f66Sowenca 1530a4c62f66Sowenca BaseCode = "template<typename T>\n" 1531a4c62f66Sowenca "T Pi = 3.14;"; 1532a4c62f66Sowenca ConstrainedCode = "template<typename T>\n" 15339aab0db1SBjörn Schäpers " requires Foo<T>\n" 1534a4c62f66Sowenca "T Pi = 3.14;"; 1535a4c62f66Sowenca BaseTokenCount = 11; 1536a4c62f66Sowenca RequiresTokenCount = 5; 1537a4c62f66Sowenca PrefixTokenCount = 5; 1538a4c62f66Sowenca TestRequires(__LINE__); 15399aab0db1SBjörn Schäpers 1540a4c62f66Sowenca BaseCode = "template<typename T>\n" 1541a4c62f66Sowenca "struct Bar;"; 1542a4c62f66Sowenca ConstrainedCode = "template<typename T>\n" 15439aab0db1SBjörn Schäpers " requires Foo<T>\n" 1544a4c62f66Sowenca "struct Bar;"; 1545a4c62f66Sowenca BaseTokenCount = 9; 1546a4c62f66Sowenca TestRequires(__LINE__); 15479aab0db1SBjörn Schäpers 1548a4c62f66Sowenca BaseCode = "template<typename T>\n" 1549a4c62f66Sowenca "struct Bar {\n" 15509aab0db1SBjörn Schäpers " T foo();\n" 15519aab0db1SBjörn Schäpers " T bar();\n" 1552a4c62f66Sowenca "};"; 1553a4c62f66Sowenca ConstrainedCode = "template<typename T>\n" 15549aab0db1SBjörn Schäpers " requires Foo<T>\n" 1555a4c62f66Sowenca "struct Bar {\n" 15569aab0db1SBjörn Schäpers " T foo();\n" 15579aab0db1SBjörn Schäpers " T bar();\n" 1558a4c62f66Sowenca "};"; 1559a4c62f66Sowenca BaseTokenCount = 21; 1560a4c62f66Sowenca TestRequires(__LINE__); 15619aab0db1SBjörn Schäpers 1562a4c62f66Sowenca BaseCode = "template<typename T>\n" 1563a4c62f66Sowenca "Bar(T) -> Bar<T>;"; 1564a4c62f66Sowenca ConstrainedCode = "template<typename T>\n" 15659aab0db1SBjörn Schäpers " requires Foo<T>\n" 1566a4c62f66Sowenca "Bar(T) -> Bar<T>;"; 1567a4c62f66Sowenca BaseTokenCount = 16; 1568a4c62f66Sowenca TestRequires(__LINE__); 15699aab0db1SBjörn Schäpers 1570a4c62f66Sowenca BaseCode = "template<typename T>\n" 1571a4c62f66Sowenca "T foo();"; 1572a4c62f66Sowenca ConstrainedCode = "template<typename T>\n" 15739aab0db1SBjörn Schäpers " requires Foo<T>\n" 1574a4c62f66Sowenca "T foo();"; 1575a4c62f66Sowenca BaseTokenCount = 11; 1576a4c62f66Sowenca TestRequires(__LINE__); 15779aab0db1SBjörn Schäpers 1578a4c62f66Sowenca BaseCode = "template<typename T>\n" 15799aab0db1SBjörn Schäpers "T foo() {\n" 15809aab0db1SBjörn Schäpers " auto bar = baz();\n" 15819aab0db1SBjörn Schäpers " return bar + T{};\n" 1582a4c62f66Sowenca "}"; 1583a4c62f66Sowenca ConstrainedCode = "template<typename T>\n" 15849aab0db1SBjörn Schäpers " requires Foo<T>\n" 15859aab0db1SBjörn Schäpers "T foo() {\n" 15869aab0db1SBjörn Schäpers " auto bar = baz();\n" 15879aab0db1SBjörn Schäpers " return bar + T{};\n" 1588a4c62f66Sowenca "}"; 1589a4c62f66Sowenca BaseTokenCount = 26; 1590a4c62f66Sowenca TestRequires(__LINE__); 15919aab0db1SBjörn Schäpers 1592a4c62f66Sowenca BaseCode = "template<typename T>\n" 1593a4c62f66Sowenca "T foo();"; 1594a4c62f66Sowenca ConstrainedCode = "template<typename T>\n" 1595a4c62f66Sowenca "T foo() requires Foo<T>;"; 1596a4c62f66Sowenca BaseTokenCount = 11; 1597a4c62f66Sowenca PrefixTokenCount = 9; 1598a4c62f66Sowenca TestRequires(__LINE__); 15999aab0db1SBjörn Schäpers 1600a4c62f66Sowenca BaseCode = "template<typename T>\n" 16019aab0db1SBjörn Schäpers "T foo() {\n" 16029aab0db1SBjörn Schäpers " auto bar = baz();\n" 16039aab0db1SBjörn Schäpers " return bar + T{};\n" 1604a4c62f66Sowenca "}"; 1605a4c62f66Sowenca ConstrainedCode = "template<typename T>\n" 16069aab0db1SBjörn Schäpers "T foo() requires Foo<T> {\n" 16079aab0db1SBjörn Schäpers " auto bar = baz();\n" 16089aab0db1SBjörn Schäpers " return bar + T{};\n" 1609a4c62f66Sowenca "}"; 1610a4c62f66Sowenca BaseTokenCount = 26; 1611a4c62f66Sowenca TestRequires(__LINE__); 16129aab0db1SBjörn Schäpers 1613a4c62f66Sowenca BaseCode = "template<typename T>\n" 16148dab4527SEmilia Dreamer "T foo();"; 16158dab4527SEmilia Dreamer ConstrainedCode = "template<typename T>\n" 16168dab4527SEmilia Dreamer " requires(Foo<T>)\n" 16178dab4527SEmilia Dreamer "T foo();"; 16188dab4527SEmilia Dreamer BaseTokenCount = 11; 16198dab4527SEmilia Dreamer RequiresTokenCount = 7; 16208dab4527SEmilia Dreamer PrefixTokenCount = 5; 16218dab4527SEmilia Dreamer TestRequires(__LINE__); 16228dab4527SEmilia Dreamer 16238dab4527SEmilia Dreamer BaseCode = "template<typename T>\n" 1624a4c62f66Sowenca "Bar(T) -> Bar<typename T::I>;"; 1625a4c62f66Sowenca ConstrainedCode = "template<typename T>\n" 16269aab0db1SBjörn Schäpers " requires requires(T &&t) {\n" 16279aab0db1SBjörn Schäpers " typename T::I;\n" 16289aab0db1SBjörn Schäpers " }\n" 1629a4c62f66Sowenca "Bar(T) -> Bar<typename T::I>;"; 1630a4c62f66Sowenca BaseTokenCount = 19; 1631a4c62f66Sowenca RequiresTokenCount = 14; 1632a4c62f66Sowenca PrefixTokenCount = 5; 1633a4c62f66Sowenca TestRequires(__LINE__); 16349aab0db1SBjörn Schäpers 1635a4c62f66Sowenca BaseCode = "struct [[nodiscard]] zero_t {\n" 1636be9a7fddSBjörn Schäpers " template<class T>\n" 1637a4c62f66Sowenca " [[nodiscard]] constexpr operator T() const { return v<T>; }\n" 1638a4c62f66Sowenca "};"; 1639a4c62f66Sowenca ConstrainedCode = 1640a4c62f66Sowenca "struct [[nodiscard]] zero_t {\n" 1641be9a7fddSBjörn Schäpers " template<class T>\n" 1642a4c62f66Sowenca " requires requires { v<T>; }\n" 1643a4c62f66Sowenca " [[nodiscard]] constexpr operator T() const { return v<T>; }\n" 1644a4c62f66Sowenca "};"; 1645a4c62f66Sowenca BaseTokenCount = 35; 1646a4c62f66Sowenca RequiresTokenCount = 9; 1647a4c62f66Sowenca PrefixTokenCount = 13; 1648a4c62f66Sowenca TestRequires(__LINE__); 1649be9a7fddSBjörn Schäpers 1650a4c62f66Sowenca BaseCode = "constexpr Foo(Foo const &other)\n" 16512b04c41bSBjörn Schäpers " : value{other.value} {\n" 16522b04c41bSBjörn Schäpers " do_magic();\n" 16532b04c41bSBjörn Schäpers " do_more_magic();\n" 1654a4c62f66Sowenca "}"; 1655a4c62f66Sowenca ConstrainedCode = "constexpr Foo(Foo const &other)\n" 16562b04c41bSBjörn Schäpers " requires std::is_copy_constructible<T>\n" 16572b04c41bSBjörn Schäpers " : value{other.value} {\n" 16582b04c41bSBjörn Schäpers " do_magic();\n" 16592b04c41bSBjörn Schäpers " do_more_magic();\n" 1660a4c62f66Sowenca "}"; 1661a4c62f66Sowenca BaseTokenCount = 26; 1662a4c62f66Sowenca RequiresTokenCount = 7; 1663a4c62f66Sowenca PrefixTokenCount = 8; 1664a4c62f66Sowenca TestRequires(__LINE__); 16652b04c41bSBjörn Schäpers 1666a4c62f66Sowenca BaseCode = "constexpr Foo(Foo const &other)\n" 16672b04c41bSBjörn Schäpers " : value{other.value} {\n" 16682b04c41bSBjörn Schäpers " do_magic();\n" 16692b04c41bSBjörn Schäpers " do_more_magic();\n" 1670a4c62f66Sowenca "}"; 1671a4c62f66Sowenca ConstrainedCode = "constexpr Foo(Foo const &other)\n" 16722b04c41bSBjörn Schäpers " requires (std::is_copy_constructible<T>)\n" 16732b04c41bSBjörn Schäpers " : value{other.value} {\n" 16742b04c41bSBjörn Schäpers " do_magic();\n" 16752b04c41bSBjörn Schäpers " do_more_magic();\n" 1676a4c62f66Sowenca "}"; 1677a4c62f66Sowenca RequiresTokenCount = 9; 1678a4c62f66Sowenca TestRequires(__LINE__); 1679c280bed8SBjörn Schäpers 1680c280bed8SBjörn Schäpers BaseCode = "template<typename T>\n" 1681c280bed8SBjörn Schäpers "ANNOTATE(\"S\"\n" 1682c280bed8SBjörn Schäpers " \"S\")\n" 1683c280bed8SBjörn Schäpers "void foo();"; 1684c280bed8SBjörn Schäpers ConstrainedCode = "template<typename T>\n" 1685c280bed8SBjörn Schäpers " requires(true)\n" 1686c280bed8SBjörn Schäpers "ANNOTATE(\"S\"\n" 1687c280bed8SBjörn Schäpers " \"S\")\n" 1688c280bed8SBjörn Schäpers "void foo();"; 1689c280bed8SBjörn Schäpers BaseTokenCount = 16; 1690c280bed8SBjörn Schäpers RequiresTokenCount = 4; 1691c280bed8SBjörn Schäpers PrefixTokenCount = 5; 1692c280bed8SBjörn Schäpers TestRequires(__LINE__); 16932601355dSowenca } 16949aab0db1SBjörn Schäpers 169535abbf16SBjörn Schäpers TEST_F(TokenAnnotatorTest, UnderstandsAsm) { 169635abbf16SBjörn Schäpers auto Tokens = annotate("__asm{\n" 1697a10135f4SGedare Bloom "\"a\":\n" 1698a10135f4SGedare Bloom ": x\n" 1699a10135f4SGedare Bloom ":};"); 1700a10135f4SGedare Bloom ASSERT_EQ(Tokens.size(), 10u) << Tokens; 170135abbf16SBjörn Schäpers EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); 170235abbf16SBjörn Schäpers EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_InlineASMBrace); 1703a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); 1704a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); 1705a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); 1706a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); 1707a10135f4SGedare Bloom 1708a10135f4SGedare Bloom Tokens = annotate("__asm(\n" 1709a10135f4SGedare Bloom "\"a\":\n" 1710a10135f4SGedare Bloom ": x\n" 1711a10135f4SGedare Bloom ":);"); 1712a10135f4SGedare Bloom ASSERT_EQ(Tokens.size(), 10u) << Tokens; 1713a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); 1714a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); 1715a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); 1716a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); 1717a10135f4SGedare Bloom 1718a10135f4SGedare Bloom Tokens = annotate("asm volatile (\n" 1719a10135f4SGedare Bloom "\"a_label:\"\n" 1720a10135f4SGedare Bloom ":\n" 1721a10135f4SGedare Bloom ": x\n" 1722a10135f4SGedare Bloom ":);"); 1723a10135f4SGedare Bloom ASSERT_EQ(Tokens.size(), 11u) << Tokens; 1724a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); 1725a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); 1726a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); 1727a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); 1728a10135f4SGedare Bloom 1729a10135f4SGedare Bloom Tokens = annotate("__asm__(\n" 1730a10135f4SGedare Bloom "\"a_label:\"\n" 1731a10135f4SGedare Bloom ": x\n" 1732a10135f4SGedare Bloom ":\n" 1733a10135f4SGedare Bloom ": y);"); 1734a10135f4SGedare Bloom ASSERT_EQ(Tokens.size(), 11u) << Tokens; 1735a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); 1736a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); 1737a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); 1738a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); 1739a10135f4SGedare Bloom 1740a10135f4SGedare Bloom Tokens = annotate("__asm volatile (\n" 1741a10135f4SGedare Bloom "\"a_label:\"\n" 1742a10135f4SGedare Bloom "\"a b c(%%x)\"\n" 1743a10135f4SGedare Bloom ":\n" 1744a10135f4SGedare Bloom ": x\n" 1745a10135f4SGedare Bloom ":);"); 1746a10135f4SGedare Bloom ASSERT_EQ(Tokens.size(), 12u) << Tokens; 1747a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); 1748a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); 1749a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); 1750a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[8], tok::colon, TT_InlineASMColon); 1751a10135f4SGedare Bloom 1752a10135f4SGedare Bloom Tokens = annotate("asm(\n" 1753a10135f4SGedare Bloom "\"insn\"\n" 1754a10135f4SGedare Bloom ": \"=r\" (var1), \"=&r\" (value)\n" 1755a10135f4SGedare Bloom ":\n" 1756a10135f4SGedare Bloom ": \"memory\");"); 1757a10135f4SGedare Bloom ASSERT_EQ(Tokens.size(), 19u) << Tokens; 1758a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); 1759a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); 1760a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[13], tok::colon, TT_InlineASMColon); 1761a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[14], tok::colon, TT_InlineASMColon); 1762a10135f4SGedare Bloom 1763a10135f4SGedare Bloom Tokens = annotate("__asm__ volatile (\n" 1764a10135f4SGedare Bloom "\"ldr r1, [r0, %%[sym]]\"\n" 1765a10135f4SGedare Bloom ":\n" 1766a10135f4SGedare Bloom ": [sym] \"J\" (aaaaa(aaaa, aaaa))\n" 1767a10135f4SGedare Bloom ");"); 1768a10135f4SGedare Bloom ASSERT_EQ(Tokens.size(), 21u) << Tokens; 1769a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); 1770a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); 1771a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); 1772a10135f4SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::l_square, TT_InlineASMSymbolicNameLSquare); 177335abbf16SBjörn Schäpers } 177435abbf16SBjörn Schäpers 17751db81123SBjörn Schäpers TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) { 17761db81123SBjörn Schäpers auto Tokens = annotate("int (^)() = ^ ()\n" 17771db81123SBjörn Schäpers " external_source_symbol() { //\n" 17781db81123SBjörn Schäpers " return 1;\n" 17791db81123SBjörn Schäpers "};"); 17801db81123SBjörn Schäpers ASSERT_EQ(Tokens.size(), 21u) << Tokens; 17811db81123SBjörn Schäpers EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ObjCBlockLParen); 17821db81123SBjörn Schäpers EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_ObjCBlockLBrace); 17831db81123SBjörn Schäpers 17841db81123SBjörn Schäpers Tokens = annotate("int *p = ^int*(){ //\n" 17851db81123SBjörn Schäpers " return nullptr;\n" 17861db81123SBjörn Schäpers "}();"); 17871db81123SBjörn Schäpers ASSERT_EQ(Tokens.size(), 19u) << Tokens; 17881db81123SBjörn Schäpers EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_ObjCBlockLBrace); 1789a27ff170SOwen Pan 1790a27ff170SOwen Pan Tokens = annotate("id (^block)(Foo *a) = ^id _Nullable(Foo *_Nullable a) {\n" 1791a27ff170SOwen Pan " return a;\n" 1792a27ff170SOwen Pan "};"); 1793a27ff170SOwen Pan ASSERT_EQ(Tokens.size(), 27u) << Tokens; 1794a27ff170SOwen Pan EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown); // Not CtorDtorDeclName. 1795a27ff170SOwen Pan EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ObjCBlockLParen); 17961db81123SBjörn Schäpers } 17971db81123SBjörn Schäpers 17982a42a7b4SOwen Pan TEST_F(TokenAnnotatorTest, UnderstandsObjCMethodExpr) { 17992a42a7b4SOwen Pan auto Tokens = annotate("void f() {\n" 18002a42a7b4SOwen Pan " //\n" 18012a42a7b4SOwen Pan " BOOL a = [b.c n] > 1;\n" 18022a42a7b4SOwen Pan "}"); 180388d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 20u) << Tokens; 18042a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[9], tok::l_square, TT_ObjCMethodExpr); 18052a42a7b4SOwen Pan EXPECT_TOKEN(Tokens[15], tok::greater, TT_BinaryOperator); 18062a42a7b4SOwen Pan } 18072a42a7b4SOwen Pan 1808d2eda492SBjörn Schäpers TEST_F(TokenAnnotatorTest, UnderstandsLambdas) { 1809d2eda492SBjörn Schäpers auto Tokens = annotate("[]() constexpr {}"); 1810d2eda492SBjörn Schäpers ASSERT_EQ(Tokens.size(), 8u) << Tokens; 1811d2eda492SBjörn Schäpers EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 1812ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_LambdaDefinitionLParen); 1813d2eda492SBjörn Schäpers EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace); 181417fb8797SDenis Fatkulin 181578472255SEmilia Dreamer Tokens = annotate("[]() consteval {}"); 181678472255SEmilia Dreamer ASSERT_EQ(Tokens.size(), 8u) << Tokens; 181778472255SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 1818ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_LambdaDefinitionLParen); 181978472255SEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace); 182078472255SEmilia Dreamer 182178472255SEmilia Dreamer Tokens = annotate("[]() mutable {}"); 182278472255SEmilia Dreamer ASSERT_EQ(Tokens.size(), 8u) << Tokens; 182378472255SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 1824ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_LambdaDefinitionLParen); 182578472255SEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace); 182678472255SEmilia Dreamer 182778472255SEmilia Dreamer Tokens = annotate("[]() static {}"); 182878472255SEmilia Dreamer ASSERT_EQ(Tokens.size(), 8u) << Tokens; 182978472255SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 1830ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_LambdaDefinitionLParen); 183178472255SEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace); 183278472255SEmilia Dreamer 183317fb8797SDenis Fatkulin Tokens = annotate("[]() -> auto {}"); 183417fb8797SDenis Fatkulin ASSERT_EQ(Tokens.size(), 9u) << Tokens; 183524761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 1836ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_LambdaDefinitionLParen); 1837438ad9f2SOwen Pan EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow); 183817fb8797SDenis Fatkulin EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace); 183917fb8797SDenis Fatkulin 184017fb8797SDenis Fatkulin Tokens = annotate("[]() -> auto & {}"); 184117fb8797SDenis Fatkulin ASSERT_EQ(Tokens.size(), 10u) << Tokens; 184224761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 1843ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_LambdaDefinitionLParen); 1844438ad9f2SOwen Pan EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow); 184517fb8797SDenis Fatkulin EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace); 184617fb8797SDenis Fatkulin 184717fb8797SDenis Fatkulin Tokens = annotate("[]() -> auto * {}"); 184817fb8797SDenis Fatkulin ASSERT_EQ(Tokens.size(), 10u) << Tokens; 184924761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 1850ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_LambdaDefinitionLParen); 1851438ad9f2SOwen Pan EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow); 185217fb8797SDenis Fatkulin EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace); 185324761354SEmilia Dreamer 185424761354SEmilia Dreamer Tokens = annotate("[] {}"); 185524761354SEmilia Dreamer ASSERT_EQ(Tokens.size(), 5u) << Tokens; 185624761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 185724761354SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_LambdaLBrace); 185824761354SEmilia Dreamer 185924761354SEmilia Dreamer Tokens = annotate("[] noexcept {}"); 186024761354SEmilia Dreamer ASSERT_EQ(Tokens.size(), 6u) << Tokens; 186124761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 186224761354SEmilia Dreamer EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_LambdaLBrace); 186324761354SEmilia Dreamer 186424761354SEmilia Dreamer Tokens = annotate("[] -> auto {}"); 186524761354SEmilia Dreamer ASSERT_EQ(Tokens.size(), 7u) << Tokens; 186624761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 1867438ad9f2SOwen Pan EXPECT_TOKEN(Tokens[2], tok::arrow, TT_LambdaArrow); 186824761354SEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_LambdaLBrace); 186924761354SEmilia Dreamer 187082e19318SOwen Pan Tokens = annotate("[] -> struct S { return {}; }"); 187182e19318SOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 187282e19318SOwen Pan EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 1873438ad9f2SOwen Pan EXPECT_TOKEN(Tokens[2], tok::arrow, TT_LambdaArrow); 187482e19318SOwen Pan EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace); 187582e19318SOwen Pan 187680303cb2SOwen Pan Tokens = annotate("foo([&](u32 bar) __attribute__((attr)) -> void {});"); 187780303cb2SOwen Pan ASSERT_EQ(Tokens.size(), 22u) << Tokens; 187880303cb2SOwen Pan EXPECT_TOKEN(Tokens[2], tok::l_square, TT_LambdaLSquare); 1879ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_LambdaDefinitionLParen); 1880438ad9f2SOwen Pan EXPECT_TOKEN(Tokens[15], tok::arrow, TT_LambdaArrow); 188180303cb2SOwen Pan EXPECT_TOKEN(Tokens[17], tok::l_brace, TT_LambdaLBrace); 188280303cb2SOwen Pan 188324761354SEmilia Dreamer Tokens = annotate("[] <typename T> () {}"); 188424761354SEmilia Dreamer ASSERT_EQ(Tokens.size(), 11u) << Tokens; 188524761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 188624761354SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 1887ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_LambdaDefinitionLParen); 188824761354SEmilia Dreamer EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_LambdaLBrace); 188924761354SEmilia Dreamer 189024761354SEmilia Dreamer Tokens = annotate("[] <typename T> {}"); 189124761354SEmilia Dreamer ASSERT_EQ(Tokens.size(), 9u) << Tokens; 189224761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 189324761354SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 189424761354SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace); 189524761354SEmilia Dreamer 189624761354SEmilia Dreamer Tokens = annotate("[] <typename... T> () {}"); 189724761354SEmilia Dreamer ASSERT_EQ(Tokens.size(), 12u) << Tokens; 189824761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 189924761354SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 1900ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_LambdaDefinitionLParen); 190124761354SEmilia Dreamer EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace); 190224761354SEmilia Dreamer 190324761354SEmilia Dreamer Tokens = annotate("[] <typename... T> {}"); 190424761354SEmilia Dreamer ASSERT_EQ(Tokens.size(), 10u) << Tokens; 190524761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 190624761354SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 190724761354SEmilia Dreamer EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace); 190824761354SEmilia Dreamer 190924761354SEmilia Dreamer Tokens = annotate("[] <int... T> () {}"); 191024761354SEmilia Dreamer ASSERT_EQ(Tokens.size(), 12u) << Tokens; 191124761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 191224761354SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 1913ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_LambdaDefinitionLParen); 191424761354SEmilia Dreamer EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace); 191524761354SEmilia Dreamer 191624761354SEmilia Dreamer Tokens = annotate("[] <int... T> {}"); 191724761354SEmilia Dreamer ASSERT_EQ(Tokens.size(), 10u) << Tokens; 191824761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 191924761354SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 192024761354SEmilia Dreamer EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace); 192124761354SEmilia Dreamer 192224761354SEmilia Dreamer Tokens = annotate("[] <Foo... T> () {}"); 192324761354SEmilia Dreamer ASSERT_EQ(Tokens.size(), 12u) << Tokens; 192424761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 192524761354SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 1926ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_LambdaDefinitionLParen); 192724761354SEmilia Dreamer EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace); 192824761354SEmilia Dreamer 192924761354SEmilia Dreamer Tokens = annotate("[] <Foo... T> {}"); 193024761354SEmilia Dreamer ASSERT_EQ(Tokens.size(), 10u) << Tokens; 193124761354SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 193224761354SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 193324761354SEmilia Dreamer EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace); 19345409fb38SEmilia Dreamer 19355409fb38SEmilia Dreamer // Lambdas with a requires-clause 19365409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> (T t) requires Bar<T> {}"); 19375409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 18u) << Tokens; 19385409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 19395409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 1940ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_LambdaDefinitionLParen); 19415409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[10], tok::kw_requires, TT_RequiresClause); 19425409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[14]->ClosesRequiresClause); 19435409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_LambdaLBrace); 19445409fb38SEmilia Dreamer 19455409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> (T &&t) requires Bar<T> {}"); 19465409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 19u) << Tokens; 19475409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 19485409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 1949ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_LambdaDefinitionLParen); 19505409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[8], tok::ampamp, TT_PointerOrReference); 19515409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause); 19525409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[15]->ClosesRequiresClause); 19535409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[16], tok::l_brace, TT_LambdaLBrace); 19545409fb38SEmilia Dreamer 19555409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> (T t) requires Foo<T> || Bar<T> {}"); 19565409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 23u) << Tokens; 19575409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 19585409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 1959ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_LambdaDefinitionLParen); 19605409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[10], tok::kw_requires, TT_RequiresClause); 19615409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[19]->ClosesRequiresClause); 19625409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[20], tok::l_brace, TT_LambdaLBrace); 19635409fb38SEmilia Dreamer 19645409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> (T t) -> T requires Bar<T> {}"); 19655409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 20u) << Tokens; 19665409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 19675409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 1968ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_LambdaDefinitionLParen); 1969438ad9f2SOwen Pan EXPECT_TOKEN(Tokens[10], tok::arrow, TT_LambdaArrow); 19705409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[12], tok::kw_requires, TT_RequiresClause); 19715409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[16]->ClosesRequiresClause); 19725409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[17], tok::l_brace, TT_LambdaLBrace); 19735409fb38SEmilia Dreamer 19745409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> requires Bar<T> (T t) {}"); 19755409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 18u) << Tokens; 19765409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 19775409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 19785409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 19795409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[10]->ClosesRequiresClause); 1980ccae7b46SGedare Bloom // FIXME: 1981ccae7b46SGedare Bloom // EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_LambdaDefinitionLParen); 19825409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_LambdaLBrace); 19835409fb38SEmilia Dreamer 19845409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> requires Bar<T> (T &&t) {}"); 19855409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 19u) << Tokens; 19865409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 19875409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 19885409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 19895409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[10]->ClosesRequiresClause); 1990ccae7b46SGedare Bloom // FIXME: 1991ccae7b46SGedare Bloom // EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_LambdaDefinitionLParen); 19925409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_PointerOrReference); 19935409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[16], tok::l_brace, TT_LambdaLBrace); 19945409fb38SEmilia Dreamer 19955409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> requires Foo<T> || Bar<T> (T t) {}"); 19965409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 23u) << Tokens; 19975409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 19985409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 19995409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 20005409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[15]->ClosesRequiresClause); 2001ccae7b46SGedare Bloom // FIXME: 2002ccae7b46SGedare Bloom // EXPECT_TOKEN(Tokens[16], tok::l_paren, TT_LambdaDefinitionLParen); 20035409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[20], tok::l_brace, TT_LambdaLBrace); 20045409fb38SEmilia Dreamer 20055409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> requires true (T&& t) {}"); 20065409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 16u) << Tokens; 20075409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 20085409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 20095409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 20105409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[7]->ClosesRequiresClause); 2011ccae7b46SGedare Bloom // FIXME: 2012ccae7b46SGedare Bloom // EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_LambdaDefinitionLParen); 20135409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_PointerOrReference); 20145409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_LambdaLBrace); 20155409fb38SEmilia Dreamer 20165409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> requires Bar<T> {}"); 20175409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 14u) << Tokens; 20185409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 20195409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 20205409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 20215409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[10]->ClosesRequiresClause); 20225409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_LambdaLBrace); 20235409fb38SEmilia Dreamer 20245409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> requires Bar<T> noexcept {}"); 20255409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 15u) << Tokens; 20265409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 20275409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 20285409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 20295409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[10]->ClosesRequiresClause); 20305409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_LambdaLBrace); 20315409fb38SEmilia Dreamer 20325409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> requires Bar<T> -> T {}"); 20335409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 16u) << Tokens; 20345409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 20355409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 20365409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 20375409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[10]->ClosesRequiresClause); 2038438ad9f2SOwen Pan EXPECT_TOKEN(Tokens[11], tok::arrow, TT_LambdaArrow); 20395409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_LambdaLBrace); 20405409fb38SEmilia Dreamer 20415409fb38SEmilia Dreamer Tokens = annotate("[] <typename T> requires Foo<T> (T t) requires Bar<T> {}"); 20425409fb38SEmilia Dreamer ASSERT_EQ(Tokens.size(), 23u) << Tokens; 20435409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 20445409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 20455409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause); 20465409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[10]->ClosesRequiresClause); 2047ccae7b46SGedare Bloom // FIXME: 2048ccae7b46SGedare Bloom // EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_LambdaDefinitionLParen); 20495409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[15], tok::kw_requires, TT_RequiresClause); 20505409fb38SEmilia Dreamer EXPECT_TRUE(Tokens[19]->ClosesRequiresClause); 20515409fb38SEmilia Dreamer EXPECT_TOKEN(Tokens[20], tok::l_brace, TT_LambdaLBrace); 20525f4ed780SEmilia Kond 20535f4ed780SEmilia Kond Tokens = annotate("[] <typename T = int> (T t) {}"); 20545f4ed780SEmilia Kond ASSERT_EQ(Tokens.size(), 15u) << Tokens; 20555f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 20565f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 20575f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser); 2058ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_LambdaDefinitionLParen); 20595f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_LambdaLBrace); 20605f4ed780SEmilia Kond 20615f4ed780SEmilia Kond Tokens = annotate("[] <int I = 0> (T t) {}"); 20625f4ed780SEmilia Kond ASSERT_EQ(Tokens.size(), 15u) << Tokens; 20635f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 20645f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 20655f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser); 2066ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_LambdaDefinitionLParen); 20675f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_LambdaLBrace); 20685f4ed780SEmilia Kond 20695f4ed780SEmilia Kond Tokens = annotate("[] <bool b = false> (T t) {}"); 20705f4ed780SEmilia Kond ASSERT_EQ(Tokens.size(), 15u) << Tokens; 20715f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 20725f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 20735f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser); 2074ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_LambdaDefinitionLParen); 20755f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_LambdaLBrace); 20765f4ed780SEmilia Kond 20775f4ed780SEmilia Kond Tokens = annotate("[] <bool b = true && false> (T&& t) {}"); 20785f4ed780SEmilia Kond ASSERT_EQ(Tokens.size(), 18u) << Tokens; 20795f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 20805f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 20815f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[7], tok::ampamp, TT_BinaryOperator); 20825f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[9], tok::greater, TT_TemplateCloser); 2083ccae7b46SGedare Bloom EXPECT_TOKEN(Tokens[10], tok::l_paren, TT_LambdaDefinitionLParen); 20845f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[12], tok::ampamp, TT_PointerOrReference); 20855f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_LambdaLBrace); 20865f4ed780SEmilia Kond 20875f4ed780SEmilia Kond Tokens = annotate("[] <typename T = int> requires Foo<T> (T t) {}"); 20885f4ed780SEmilia Kond ASSERT_EQ(Tokens.size(), 20u) << Tokens; 20895f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); 20905f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 20915f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser); 20925f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[8], tok::kw_requires, TT_RequiresClause); 2093ccae7b46SGedare Bloom // FIXME: 2094ccae7b46SGedare Bloom // EXPECT_TOKEN(Tokens[13], tok::l_paren, TT_LambdaDefinitionLParen); 20955f4ed780SEmilia Kond EXPECT_TOKEN(Tokens[17], tok::l_brace, TT_LambdaLBrace); 2096d2eda492SBjörn Schäpers } 2097d2eda492SBjörn Schäpers 2098f54d42abSEmilia Dreamer TEST_F(TokenAnnotatorTest, UnderstandsFunctionAnnotations) { 2099f54d42abSEmilia Dreamer auto Tokens = annotate("template <typename T>\n" 2100f54d42abSEmilia Dreamer "DEPRECATED(\"Use NewClass::NewFunction instead.\")\n" 2101f54d42abSEmilia Dreamer "string OldFunction(const string ¶meter) {}"); 2102f54d42abSEmilia Dreamer ASSERT_EQ(Tokens.size(), 20u) << Tokens; 2103f54d42abSEmilia Dreamer EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_FunctionAnnotationRParen); 2104f54d42abSEmilia Dreamer 2105f54d42abSEmilia Dreamer Tokens = annotate("template <typename T>\n" 2106f54d42abSEmilia Dreamer "A(T) noexcept;"); 2107f54d42abSEmilia Dreamer ASSERT_EQ(Tokens.size(), 12u) << Tokens; 2108f54d42abSEmilia Dreamer EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown); 21090387cd05SOwen Pan 21100387cd05SOwen Pan Tokens = annotate("FOO(bar)();"); 21110387cd05SOwen Pan ASSERT_EQ(Tokens.size(), 8u) << Tokens; 21120387cd05SOwen Pan EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_Unknown); 2113f54d42abSEmilia Dreamer } 2114f54d42abSEmilia Dreamer 211596e23906SOwen Pan TEST_F(TokenAnnotatorTest, UnderstandsFunctionDeclarationNames) { 211696e23906SOwen Pan auto Tokens = annotate("void f [[noreturn]] ();"); 211796e23906SOwen Pan ASSERT_EQ(Tokens.size(), 11u) << Tokens; 211896e23906SOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 2119b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_FunctionDeclarationLParen); 212096e23906SOwen Pan 212196e23906SOwen Pan Tokens = annotate("void f [[noreturn]] () {}"); 212296e23906SOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 212396e23906SOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 2124b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_FunctionDeclarationLParen); 212508630512SOwen Pan 212608630512SOwen Pan Tokens = annotate("#define FOO Foo::\n" 212708630512SOwen Pan "FOO Foo();"); 212808630512SOwen Pan ASSERT_EQ(Tokens.size(), 11u) << Tokens; 212908630512SOwen Pan EXPECT_TOKEN(Tokens[6], tok::identifier, TT_FunctionDeclarationName); 2130b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_FunctionDeclarationLParen); 21316e608dc4SOwen Pan 21326e608dc4SOwen Pan Tokens = annotate("struct Foo {\n" 21336e608dc4SOwen Pan " Bar (*func)();\n" 21346e608dc4SOwen Pan "};"); 21356e608dc4SOwen Pan ASSERT_EQ(Tokens.size(), 14u) << Tokens; 21366e608dc4SOwen Pan EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown); 21376e608dc4SOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_FunctionTypeLParen); 2138f8f89260SOwen Pan 2139bcf849b1SOwen Pan Tokens = annotate("void instanceof();"); 214094698369SOwen Pan ASSERT_EQ(Tokens.size(), 6u) << Tokens; 2141bcf849b1SOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 2142b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); 2143bcf849b1SOwen Pan 21440baef3b1SOwen Pan Tokens = annotate("int iso_time(time_t);"); 21450baef3b1SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 21460baef3b1SOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 2147b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); 21480baef3b1SOwen Pan 2149f8f89260SOwen Pan auto Style = getLLVMStyle(); 21500baef3b1SOwen Pan Style.TypeNames.push_back("MyType"); 21510baef3b1SOwen Pan Tokens = annotate("int iso_time(MyType);", Style); 2152f8f89260SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 2153f8f89260SOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 2154b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); 2155f8f89260SOwen Pan EXPECT_TOKEN(Tokens[3], tok::identifier, TT_TypeName); 215696e23906SOwen Pan } 215796e23906SOwen Pan 21587e856d18SOwen Pan TEST_F(TokenAnnotatorTest, UnderstandsCtorAndDtorDeclNames) { 21597e856d18SOwen Pan auto Tokens = annotate("class Foo { public: Foo(); };"); 21607e856d18SOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 21617e856d18SOwen Pan EXPECT_TOKEN(Tokens[5], tok::identifier, TT_CtorDtorDeclName); 2162b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionDeclarationLParen); 21637e856d18SOwen Pan 21647e856d18SOwen Pan Tokens = annotate("class Foo { public: ~Foo(); };"); 21657e856d18SOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 21667e856d18SOwen Pan EXPECT_TOKEN(Tokens[6], tok::identifier, TT_CtorDtorDeclName); 2167b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_FunctionDeclarationLParen); 21687e856d18SOwen Pan 21697e856d18SOwen Pan Tokens = annotate("struct Foo { [[deprecated]] Foo() {} };"); 21707e856d18SOwen Pan ASSERT_EQ(Tokens.size(), 16u) << Tokens; 21717e856d18SOwen Pan EXPECT_TOKEN(Tokens[8], tok::identifier, TT_CtorDtorDeclName); 2172b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[9], tok::l_paren, TT_FunctionDeclarationLParen); 21737e856d18SOwen Pan EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_FunctionLBrace); 21747e856d18SOwen Pan 21757e856d18SOwen Pan Tokens = annotate("struct Foo { [[deprecated]] ~Foo() {} };"); 21767e856d18SOwen Pan ASSERT_EQ(Tokens.size(), 17u) << Tokens; 21777e856d18SOwen Pan EXPECT_TOKEN(Tokens[9], tok::identifier, TT_CtorDtorDeclName); 2178b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[10], tok::l_paren, TT_FunctionDeclarationLParen); 21797e856d18SOwen Pan EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_FunctionLBrace); 21807e856d18SOwen Pan 21817e856d18SOwen Pan Tokens = annotate("struct Foo { Foo() [[deprecated]] {} };"); 21827e856d18SOwen Pan ASSERT_EQ(Tokens.size(), 16u) << Tokens; 21837e856d18SOwen Pan EXPECT_TOKEN(Tokens[3], tok::identifier, TT_CtorDtorDeclName); 2184b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_FunctionDeclarationLParen); 21857e856d18SOwen Pan EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_FunctionLBrace); 21867e856d18SOwen Pan 21877e856d18SOwen Pan Tokens = annotate("struct Foo { ~Foo() [[deprecated]] {} };"); 21887e856d18SOwen Pan ASSERT_EQ(Tokens.size(), 17u) << Tokens; 21897e856d18SOwen Pan EXPECT_TOKEN(Tokens[4], tok::identifier, TT_CtorDtorDeclName); 2190b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_FunctionDeclarationLParen); 21917e856d18SOwen Pan EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_FunctionLBrace); 21927e856d18SOwen Pan 21937e856d18SOwen Pan Tokens = annotate("struct Foo { [[deprecated]] explicit Foo() {} };"); 21947e856d18SOwen Pan ASSERT_EQ(Tokens.size(), 17u) << Tokens; 21957e856d18SOwen Pan EXPECT_TOKEN(Tokens[9], tok::identifier, TT_CtorDtorDeclName); 2196b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[10], tok::l_paren, TT_FunctionDeclarationLParen); 21977e856d18SOwen Pan EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_FunctionLBrace); 21987e856d18SOwen Pan 21997e856d18SOwen Pan Tokens = annotate("struct Foo { virtual [[deprecated]] ~Foo() {} };"); 22007e856d18SOwen Pan ASSERT_EQ(Tokens.size(), 18u) << Tokens; 22017e856d18SOwen Pan EXPECT_TOKEN(Tokens[10], tok::identifier, TT_CtorDtorDeclName); 2202b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_FunctionDeclarationLParen); 22037e856d18SOwen Pan EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_FunctionLBrace); 22047e856d18SOwen Pan 22057e856d18SOwen Pan Tokens = annotate("Foo::Foo() {}"); 22067e856d18SOwen Pan ASSERT_EQ(Tokens.size(), 8u) << Tokens; 22077e856d18SOwen Pan EXPECT_TOKEN(Tokens[2], tok::identifier, TT_CtorDtorDeclName); 2208b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_FunctionDeclarationLParen); 22097e856d18SOwen Pan EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_FunctionLBrace); 22107e856d18SOwen Pan 22117e856d18SOwen Pan Tokens = annotate("Foo::~Foo() {}"); 22127e856d18SOwen Pan ASSERT_EQ(Tokens.size(), 9u) << Tokens; 22137e856d18SOwen Pan EXPECT_TOKEN(Tokens[3], tok::identifier, TT_CtorDtorDeclName); 2214b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_FunctionDeclarationLParen); 22157e856d18SOwen Pan EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_FunctionLBrace); 22167e856d18SOwen Pan 22177e856d18SOwen Pan Tokens = annotate("struct Test {\n" 22187e856d18SOwen Pan " Test()\n" 22197e856d18SOwen Pan " : l([] {\n" 22207e856d18SOwen Pan " Short::foo();\n" 22217e856d18SOwen Pan " }) {}\n" 22227e856d18SOwen Pan "};"); 22237e856d18SOwen Pan ASSERT_EQ(Tokens.size(), 25u) << Tokens; 22247e856d18SOwen Pan EXPECT_TOKEN(Tokens[3], tok::identifier, TT_CtorDtorDeclName); 2225b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_FunctionDeclarationLParen); 22267e856d18SOwen Pan EXPECT_TOKEN(Tokens[14], tok::identifier, TT_Unknown); 22277e856d18SOwen Pan } 22287e856d18SOwen Pan 22290904e0baSEmilia Dreamer TEST_F(TokenAnnotatorTest, UnderstandsC11GenericSelection) { 22300904e0baSEmilia Dreamer auto Tokens = annotate("_Generic(x, int: 1, default: 0)"); 22310904e0baSEmilia Dreamer ASSERT_EQ(Tokens.size(), 13u) << Tokens; 22320904e0baSEmilia Dreamer EXPECT_TOKEN(Tokens[0], tok::kw__Generic, TT_Unknown); 22330904e0baSEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::colon, TT_GenericSelectionColon); 22340904e0baSEmilia Dreamer EXPECT_TOKEN(Tokens[9], tok::colon, TT_GenericSelectionColon); 22350904e0baSEmilia Dreamer } 22360904e0baSEmilia Dreamer 2237fd867899SEmilia Dreamer TEST_F(TokenAnnotatorTest, UnderstandsTrailingReturnArrow) { 2238fd867899SEmilia Dreamer auto Tokens = annotate("auto f() -> int;"); 2239fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 8u) << Tokens; 2240fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::arrow, TT_TrailingReturnArrow); 2241fd867899SEmilia Dreamer 2242fd867899SEmilia Dreamer Tokens = annotate("auto operator->() -> int;"); 2243fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 9u) << Tokens; 2244fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[2], tok::arrow, TT_OverloadedOperator); 2245fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::arrow, TT_TrailingReturnArrow); 2246fd867899SEmilia Dreamer 2247fd867899SEmilia Dreamer Tokens = annotate("auto operator++(int) -> int;"); 2248fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 10u) << Tokens; 2249fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::arrow, TT_TrailingReturnArrow); 2250fd867899SEmilia Dreamer 2251fd867899SEmilia Dreamer Tokens = annotate("auto operator=() -> int;"); 2252fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 9u) << Tokens; 2253fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[5], tok::arrow, TT_TrailingReturnArrow); 2254fd867899SEmilia Dreamer 2255fd867899SEmilia Dreamer Tokens = annotate("auto operator=(int) -> int;"); 2256fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 10u) << Tokens; 2257fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::arrow, TT_TrailingReturnArrow); 2258fd867899SEmilia Dreamer 2259fd867899SEmilia Dreamer Tokens = annotate("auto foo() -> auto { return Val; }"); 2260fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 12u) << Tokens; 2261fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::arrow, TT_TrailingReturnArrow); 2262fd867899SEmilia Dreamer 2263fd867899SEmilia Dreamer Tokens = annotate("struct S { auto bar() const -> int; };"); 2264fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 14u) << Tokens; 2265fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[8], tok::arrow, TT_TrailingReturnArrow); 2266fd867899SEmilia Dreamer 2267fd867899SEmilia Dreamer // Not trailing return arrows 2268fd867899SEmilia Dreamer Tokens = annotate("auto a = b->c;"); 2269fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 8u) << Tokens; 2270fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::arrow, TT_Unknown); 2271fd867899SEmilia Dreamer 2272fd867899SEmilia Dreamer Tokens = annotate("auto a = (b)->c;"); 2273fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 10u) << Tokens; 2274fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::arrow, TT_Unknown); 2275fd867899SEmilia Dreamer 2276fd867899SEmilia Dreamer Tokens = annotate("auto a = b()->c;"); 2277fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 10u) << Tokens; 2278fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[6], tok::arrow, TT_Unknown); 2279fd867899SEmilia Dreamer 2280fd867899SEmilia Dreamer Tokens = annotate("auto a = b->c();"); 2281fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 10u) << Tokens; 2282fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::arrow, TT_Unknown); 2283fd867899SEmilia Dreamer 2284fd867899SEmilia Dreamer Tokens = annotate("decltype(auto) a = b()->c;"); 2285fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 13u) << Tokens; 2286fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[9], tok::arrow, TT_Unknown); 2287fd867899SEmilia Dreamer 2288fd867899SEmilia Dreamer Tokens = annotate("void f() { auto a = b->c(); }"); 2289fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 16u) << Tokens; 2290fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[9], tok::arrow, TT_Unknown); 2291fd867899SEmilia Dreamer 2292fd867899SEmilia Dreamer Tokens = annotate("void f() { auto a = b()->c; }"); 2293fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 16u) << Tokens; 2294fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[11], tok::arrow, TT_Unknown); 2295fd867899SEmilia Dreamer 2296c83d64f1SOwen Pan Tokens = annotate("#define P(ptr) auto p = (ptr)->p"); 2297c83d64f1SOwen Pan ASSERT_EQ(Tokens.size(), 15u) << Tokens; 2298c83d64f1SOwen Pan EXPECT_TOKEN(Tokens[12], tok::arrow, TT_Unknown); 2299c83d64f1SOwen Pan 23000ae998c4SOwen Pan Tokens = annotate("void f() FOO(foo->bar);"); 23010ae998c4SOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 23020ae998c4SOwen Pan EXPECT_TOKEN(Tokens[7], tok::arrow, TT_Unknown); 23030ae998c4SOwen Pan 2304a7f4576fSOwen Pan Tokens = annotate("__attribute__((cold)) C() : Base(obj->func()) {}"); 2305a7f4576fSOwen Pan ASSERT_EQ(Tokens.size(), 21u) << Tokens; 2306a7f4576fSOwen Pan EXPECT_TOKEN(Tokens[13], tok::arrow, TT_Unknown); 2307a7f4576fSOwen Pan 2308b1b60d4cSOwen Pan Tokens = annotate("Class<Type>{foo}->func(arg);"); 2309b1b60d4cSOwen Pan ASSERT_EQ(Tokens.size(), 14u) << Tokens; 2310b1b60d4cSOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_Unknown); // Not FunctionLBrace 2311b1b60d4cSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_BracedInit); 2312b1b60d4cSOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_BracedInit); 2313b1b60d4cSOwen Pan EXPECT_TOKEN(Tokens[7], tok::arrow, TT_Unknown); 2314b1b60d4cSOwen Pan 2315dcebe297SOwen Pan auto Style = getLLVMStyle(); 2316dcebe297SOwen Pan Style.StatementAttributeLikeMacros.push_back("emit"); 2317dcebe297SOwen Pan Tokens = annotate("emit foo()->bar;", Style); 2318dcebe297SOwen Pan ASSERT_EQ(Tokens.size(), 8u) << Tokens; 2319dcebe297SOwen Pan EXPECT_TOKEN(Tokens[0], tok::identifier, TT_StatementAttributeLikeMacro); 2320dcebe297SOwen Pan EXPECT_TOKEN(Tokens[4], tok::arrow, TT_Unknown); 2321dcebe297SOwen Pan 2322fd867899SEmilia Dreamer // Mixed 2323fd867899SEmilia Dreamer Tokens = annotate("auto f() -> int { auto a = b()->c; }"); 2324fd867899SEmilia Dreamer ASSERT_EQ(Tokens.size(), 18u) << Tokens; 2325fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[4], tok::arrow, TT_TrailingReturnArrow); 2326fd867899SEmilia Dreamer EXPECT_TOKEN(Tokens[13], tok::arrow, TT_Unknown); 2327fd867899SEmilia Dreamer } 2328fd867899SEmilia Dreamer 2329a112921dSEmilia Kond TEST_F(TokenAnnotatorTest, UnderstandHashInMacro) { 2330a112921dSEmilia Kond auto Tokens = annotate("#define Foo(Bar) \\\n" 2331a112921dSEmilia Kond " { \\\n" 2332a112921dSEmilia Kond " #Bar \\\n" 2333a112921dSEmilia Kond " }"); 2334a112921dSEmilia Kond ASSERT_EQ(Tokens.size(), 11u) << Tokens; 233558323de2SOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_BracedInit); 233658323de2SOwen Pan EXPECT_BRACE_KIND(Tokens[9], BK_BracedInit); 2337a112921dSEmilia Kond 2338a112921dSEmilia Kond Tokens = annotate("#define Foo(Bar) \\\n" 2339a112921dSEmilia Kond " { #Bar }"); 2340a112921dSEmilia Kond ASSERT_EQ(Tokens.size(), 11u) << Tokens; 234158323de2SOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_BracedInit); 234258323de2SOwen Pan EXPECT_BRACE_KIND(Tokens[9], BK_BracedInit); 234358323de2SOwen Pan 234458323de2SOwen Pan Tokens = annotate("#define FOO(typeName, realClass) \\\n" 234558323de2SOwen Pan " {#typeName, foo<Foo>(new foo<realClass>(#typeName))}"); 234658323de2SOwen Pan ASSERT_EQ(Tokens.size(), 29u) << Tokens; 234758323de2SOwen Pan EXPECT_BRACE_KIND(Tokens[8], BK_BracedInit); 234858323de2SOwen Pan EXPECT_BRACE_KIND(Tokens[27], BK_BracedInit); 2349a112921dSEmilia Kond } 2350a112921dSEmilia Kond 23517f881a2aSJared Grubb TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacros) { 23527f881a2aSJared Grubb // '__attribute__' has special handling. 2353f06f0164SOwen Pan auto Tokens = annotate("__attribute__((X)) void Foo(void);"); 2354f06f0164SOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 23557f881a2aSJared Grubb EXPECT_TOKEN(Tokens[0], tok::kw___attribute, TT_Unknown); 23567f881a2aSJared Grubb EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_AttributeLParen); 2357f06f0164SOwen Pan EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen); 23587f881a2aSJared Grubb 23597f881a2aSJared Grubb // Generic macro has no special handling in this location. 23607f881a2aSJared Grubb Tokens = annotate("A(X) void Foo(void);"); 23617f881a2aSJared Grubb ASSERT_EQ(Tokens.size(), 11u) << Tokens; 23627f881a2aSJared Grubb EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown); 23637f881a2aSJared Grubb EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown); 23647f881a2aSJared Grubb 23657f881a2aSJared Grubb // Add a custom AttributeMacro. Test that it has the same behavior. 23667f881a2aSJared Grubb FormatStyle Style = getLLVMStyle(); 23677f881a2aSJared Grubb Style.AttributeMacros.push_back("A"); 23687f881a2aSJared Grubb 23697f881a2aSJared Grubb // An "AttributeMacro" gets annotated like '__attribute__'. 23707f881a2aSJared Grubb Tokens = annotate("A(X) void Foo(void);", Style); 23717f881a2aSJared Grubb ASSERT_EQ(Tokens.size(), 11u) << Tokens; 23727f881a2aSJared Grubb EXPECT_TOKEN(Tokens[0], tok::identifier, TT_AttributeMacro); 23737f881a2aSJared Grubb EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_AttributeLParen); 23747f881a2aSJared Grubb EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_AttributeRParen); 23757f881a2aSJared Grubb } 23767f881a2aSJared Grubb 23777f881a2aSJared Grubb TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacrosOnObjCDecl) { 23787f881a2aSJared Grubb // '__attribute__' has special handling. 2379f06f0164SOwen Pan auto Tokens = annotate("__attribute__((X)) @interface Foo"); 2380f06f0164SOwen Pan ASSERT_EQ(Tokens.size(), 10u) << Tokens; 23817f881a2aSJared Grubb EXPECT_TOKEN(Tokens[0], tok::kw___attribute, TT_Unknown); 23827f881a2aSJared Grubb EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_AttributeLParen); 2383f06f0164SOwen Pan EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen); 23847f881a2aSJared Grubb 23857f881a2aSJared Grubb // Generic macro has no special handling in this location. 23867f881a2aSJared Grubb Tokens = annotate("A(X) @interface Foo"); 23877f881a2aSJared Grubb ASSERT_EQ(Tokens.size(), 8u) << Tokens; 23887f881a2aSJared Grubb // Note: Don't check token-type as a random token in this position is hard to 23897f881a2aSJared Grubb // reason about. 23907f881a2aSJared Grubb EXPECT_TOKEN_KIND(Tokens[0], tok::identifier); 23917f881a2aSJared Grubb EXPECT_TOKEN_KIND(Tokens[1], tok::l_paren); 23927f881a2aSJared Grubb 23937f881a2aSJared Grubb // Add a custom AttributeMacro. Test that it has the same behavior. 23947f881a2aSJared Grubb FormatStyle Style = getLLVMStyle(); 23957f881a2aSJared Grubb Style.AttributeMacros.push_back("A"); 23967f881a2aSJared Grubb 23977f881a2aSJared Grubb // An "AttributeMacro" gets annotated like '__attribute__'. 23987f881a2aSJared Grubb Tokens = annotate("A(X) @interface Foo", Style); 23997f881a2aSJared Grubb ASSERT_EQ(Tokens.size(), 8u) << Tokens; 24007f881a2aSJared Grubb EXPECT_TOKEN(Tokens[0], tok::identifier, TT_AttributeMacro); 24017f881a2aSJared Grubb EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_AttributeLParen); 24027f881a2aSJared Grubb EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_AttributeRParen); 24037f881a2aSJared Grubb } 24047f881a2aSJared Grubb 24057f881a2aSJared Grubb TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacrosOnObjCMethodDecl) { 24067f881a2aSJared Grubb // '__attribute__' has special handling. 2407f06f0164SOwen Pan auto Tokens = annotate("- (id)init __attribute__((X));"); 2408f06f0164SOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 24097f881a2aSJared Grubb EXPECT_TOKEN(Tokens[5], tok::kw___attribute, TT_Unknown); 24107f881a2aSJared Grubb EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_AttributeLParen); 2411f06f0164SOwen Pan EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_AttributeRParen); 24127f881a2aSJared Grubb 24137f881a2aSJared Grubb // Generic macro has no special handling in this location. 24147f881a2aSJared Grubb Tokens = annotate("- (id)init A(X);"); 24157f881a2aSJared Grubb ASSERT_EQ(Tokens.size(), 11u) << Tokens; 24167f881a2aSJared Grubb // Note: Don't check token-type as a random token in this position is hard to 24177f881a2aSJared Grubb // reason about. 24187f881a2aSJared Grubb EXPECT_TOKEN_KIND(Tokens[5], tok::identifier); 24197f881a2aSJared Grubb EXPECT_TOKEN_KIND(Tokens[6], tok::l_paren); 24207f881a2aSJared Grubb 24217f881a2aSJared Grubb // Add a custom AttributeMacro. Test that it has the same behavior. 24227f881a2aSJared Grubb FormatStyle Style = getLLVMStyle(); 24237f881a2aSJared Grubb Style.AttributeMacros.push_back("A"); 24247f881a2aSJared Grubb 24257f881a2aSJared Grubb // An "AttributeMacro" gets annotated like '__attribute__'. 24267f881a2aSJared Grubb Tokens = annotate("- (id)init A(X);", Style); 24277f881a2aSJared Grubb ASSERT_EQ(Tokens.size(), 11u) << Tokens; 24287f881a2aSJared Grubb EXPECT_TOKEN(Tokens[5], tok::identifier, TT_AttributeMacro); 24297f881a2aSJared Grubb EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_AttributeLParen); 24307f881a2aSJared Grubb EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_AttributeRParen); 24317f881a2aSJared Grubb } 24327f881a2aSJared Grubb 24337f881a2aSJared Grubb TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacrosOnObjCProperty) { 24347f881a2aSJared Grubb // '__attribute__' has special handling. 2435f06f0164SOwen Pan auto Tokens = annotate("@property(weak) id delegate __attribute__((X));"); 2436f06f0164SOwen Pan ASSERT_EQ(Tokens.size(), 15u) << Tokens; 24377f881a2aSJared Grubb EXPECT_TOKEN(Tokens[7], tok::kw___attribute, TT_Unknown); 24387f881a2aSJared Grubb EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_AttributeLParen); 2439f06f0164SOwen Pan EXPECT_TOKEN(Tokens[12], tok::r_paren, TT_AttributeRParen); 24407f881a2aSJared Grubb 24417f881a2aSJared Grubb // Generic macro has no special handling in this location. 24427f881a2aSJared Grubb Tokens = annotate("@property(weak) id delegate A(X);"); 24437f881a2aSJared Grubb ASSERT_EQ(Tokens.size(), 13u) << Tokens; 24447f881a2aSJared Grubb // Note: Don't check token-type as a random token in this position is hard to 24457f881a2aSJared Grubb // reason about. 24467f881a2aSJared Grubb EXPECT_TOKEN_KIND(Tokens[7], tok::identifier); 24477f881a2aSJared Grubb EXPECT_TOKEN_KIND(Tokens[8], tok::l_paren); 24487f881a2aSJared Grubb 24497f881a2aSJared Grubb // Add a custom AttributeMacro. Test that it has the same behavior. 24507f881a2aSJared Grubb FormatStyle Style = getLLVMStyle(); 24517f881a2aSJared Grubb Style.AttributeMacros.push_back("A"); 24527f881a2aSJared Grubb 24537f881a2aSJared Grubb // An "AttributeMacro" gets annotated like '__attribute__'. 24547f881a2aSJared Grubb Tokens = annotate("@property(weak) id delegate A(X);", Style); 24557f881a2aSJared Grubb ASSERT_EQ(Tokens.size(), 13u) << Tokens; 24567f881a2aSJared Grubb EXPECT_TOKEN(Tokens[7], tok::identifier, TT_AttributeMacro); 24577f881a2aSJared Grubb EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_AttributeLParen); 24587f881a2aSJared Grubb EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_AttributeRParen); 24597f881a2aSJared Grubb } 24607f881a2aSJared Grubb 2461f93182a8Ssstwcw TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) { 24621c58208dSOwen Pan auto Annotate = [this](StringRef Code) { 2463f93182a8Ssstwcw return annotate(Code, getLLVMStyle(FormatStyle::LK_Verilog)); 2464f93182a8Ssstwcw }; 2465f93182a8Ssstwcw // Test that unary operators get labeled as such and that operators like '++' 2466f93182a8Ssstwcw // don't get split. 2467f93182a8Ssstwcw tok::TokenKind Unary[] = {tok::plus, tok::minus, tok::exclaim, 2468f93182a8Ssstwcw tok::tilde, tok::amp, tok::pipe, 2469f93182a8Ssstwcw tok::caret, tok::plusplus, tok::minusminus}; 2470f93182a8Ssstwcw for (auto Kind : Unary) { 2471f93182a8Ssstwcw auto Tokens = 2472f93182a8Ssstwcw Annotate(std::string("x = ") + tok::getPunctuatorSpelling(Kind) + "x;"); 2473f93182a8Ssstwcw ASSERT_EQ(Tokens.size(), 6u) << Tokens; 2474f93182a8Ssstwcw EXPECT_TOKEN(Tokens[2], Kind, TT_UnaryOperator); 2475f93182a8Ssstwcw } 2476f93182a8Ssstwcw // Operators formed by joining two operators like '^~'. For some of these 2477f93182a8Ssstwcw // joined operators, we don't have a separate type, so we only test for their 2478f93182a8Ssstwcw // precedence. 2479f93182a8Ssstwcw std::pair<prec::Level, std::string> JoinedBinary[] = { 24803af82b39Ssstwcw {prec::Comma, "->"}, {prec::Comma, "<->"}, 24813af82b39Ssstwcw {prec::Assignment, "+="}, {prec::Assignment, "-="}, 24823af82b39Ssstwcw {prec::Assignment, "*="}, {prec::Assignment, "/="}, 24833af82b39Ssstwcw {prec::Assignment, "%="}, {prec::Assignment, "&="}, 24843af82b39Ssstwcw {prec::Assignment, "^="}, {prec::Assignment, "<<="}, 24853af82b39Ssstwcw {prec::Assignment, ">>="}, {prec::Assignment, "<<<="}, 24863af82b39Ssstwcw {prec::Assignment, ">>>="}, {prec::LogicalOr, "||"}, 24873af82b39Ssstwcw {prec::LogicalAnd, "&&"}, {prec::Equality, "=="}, 24883af82b39Ssstwcw {prec::Equality, "!="}, {prec::Equality, "==="}, 24893af82b39Ssstwcw {prec::Equality, "!=="}, {prec::Equality, "==?"}, 24903af82b39Ssstwcw {prec::Equality, "!=?"}, {prec::ExclusiveOr, "~^"}, 24913af82b39Ssstwcw {prec::ExclusiveOr, "^~"}, 2492f93182a8Ssstwcw }; 2493f93182a8Ssstwcw for (auto Operator : JoinedBinary) { 2494f93182a8Ssstwcw auto Tokens = Annotate(std::string("x = x ") + Operator.second + " x;"); 2495f93182a8Ssstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 2496f93182a8Ssstwcw EXPECT_TOKEN_TYPE(Tokens[3], TT_BinaryOperator); 2497f93182a8Ssstwcw EXPECT_TOKEN_PRECEDENCE(Tokens[3], Operator.first); 2498f93182a8Ssstwcw } 2499f93182a8Ssstwcw // '~^' and '^~' can be unary as well as binary operators. 2500f93182a8Ssstwcw auto Tokens = Annotate("x = ~^x;"); 2501f93182a8Ssstwcw ASSERT_EQ(Tokens.size(), 6u) << Tokens; 2502f93182a8Ssstwcw EXPECT_TOKEN_TYPE(Tokens[2], TT_UnaryOperator); 2503f93182a8Ssstwcw Tokens = Annotate("x = ^~x;"); 2504f93182a8Ssstwcw ASSERT_EQ(Tokens.size(), 6u) << Tokens; 2505f93182a8Ssstwcw EXPECT_TOKEN_TYPE(Tokens[2], TT_UnaryOperator); 2506f93182a8Ssstwcw // The unary operators '~&' and '~|' can only be unary operators. The current 2507f93182a8Ssstwcw // implementation treats each of them as separate unary '~' and '&' or '|' 2508f93182a8Ssstwcw // operators, which is enough for formatting purposes. In FormatTestVerilog, 2509f93182a8Ssstwcw // there is a test that there is no space in between. And even if a new line 2510f93182a8Ssstwcw // is inserted between the '~' and '|', the semantic meaning is the same as 2511f93182a8Ssstwcw // the joined operator, so the CanBreakBefore property doesn't need to be 2512f93182a8Ssstwcw // false for the second operator. 2513f93182a8Ssstwcw Tokens = Annotate("x = ~&x;"); 2514f93182a8Ssstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 2515f93182a8Ssstwcw EXPECT_TOKEN(Tokens[2], tok::tilde, TT_UnaryOperator); 2516f93182a8Ssstwcw EXPECT_TOKEN(Tokens[3], tok::amp, TT_UnaryOperator); 2517f93182a8Ssstwcw Tokens = Annotate("x = ~|x;"); 2518f93182a8Ssstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 2519f93182a8Ssstwcw EXPECT_TOKEN(Tokens[2], tok::tilde, TT_UnaryOperator); 2520f93182a8Ssstwcw EXPECT_TOKEN(Tokens[3], tok::pipe, TT_UnaryOperator); 252167480b36Ssstwcw // Test for block label colons. 252267480b36Ssstwcw Tokens = Annotate("begin : x\n" 252367480b36Ssstwcw "end : x"); 2524b6301a01Ssstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 252567480b36Ssstwcw EXPECT_TOKEN(Tokens[1], tok::colon, TT_VerilogBlockLabelColon); 252667480b36Ssstwcw EXPECT_TOKEN(Tokens[4], tok::colon, TT_VerilogBlockLabelColon); 25276db0c18bSsstwcw // Test that the dimension colon is annotated correctly. 25286db0c18bSsstwcw Tokens = Annotate("var [1 : 0] x;"); 25296db0c18bSsstwcw ASSERT_EQ(Tokens.size(), 9u) << Tokens; 25306db0c18bSsstwcw EXPECT_TOKEN(Tokens[3], tok::colon, TT_BitFieldColon); 25316db0c18bSsstwcw Tokens = Annotate("extern function [1 : 0] x;"); 25326db0c18bSsstwcw ASSERT_EQ(Tokens.size(), 10u) << Tokens; 25336db0c18bSsstwcw EXPECT_TOKEN(Tokens[4], tok::colon, TT_BitFieldColon); 25344134f836Ssstwcw Tokens = Annotate("module test\n" 25354134f836Ssstwcw " (input wire [7 : 0] a[7 : 0]);\n" 25364134f836Ssstwcw "endmodule"); 25374134f836Ssstwcw ASSERT_EQ(Tokens.size(), 20u) << Tokens; 25384134f836Ssstwcw EXPECT_TOKEN(Tokens[4], tok::identifier, TT_VerilogDimensionedTypeName); 25394134f836Ssstwcw EXPECT_TOKEN(Tokens[7], tok::colon, TT_BitFieldColon); 25404134f836Ssstwcw EXPECT_TOKEN(Tokens[13], tok::colon, TT_BitFieldColon); 2541c8871948Ssstwcw // Test case labels and ternary operators. 2542c8871948Ssstwcw Tokens = Annotate("case (x)\n" 2543c8871948Ssstwcw " x:\n" 2544c8871948Ssstwcw " x;\n" 254588934a82SOwen Pan "endcase"); 2546c8871948Ssstwcw ASSERT_EQ(Tokens.size(), 10u) << Tokens; 254782a90caaSsstwcw EXPECT_TOKEN(Tokens[5], tok::colon, TT_CaseLabelColon); 2548c8871948Ssstwcw Tokens = Annotate("case (x)\n" 2549c8871948Ssstwcw " x ? x : x:\n" 2550c8871948Ssstwcw " x;\n" 255188934a82SOwen Pan "endcase"); 2552c8871948Ssstwcw ASSERT_EQ(Tokens.size(), 14u) << Tokens; 2553c8871948Ssstwcw EXPECT_TOKEN(Tokens[5], tok::question, TT_ConditionalExpr); 2554c8871948Ssstwcw EXPECT_TOKEN(Tokens[7], tok::colon, TT_ConditionalExpr); 255582a90caaSsstwcw EXPECT_TOKEN(Tokens[9], tok::colon, TT_CaseLabelColon); 2556cad708b9Ssstwcw // Non-blocking assignments. 2557cad708b9Ssstwcw Tokens = Annotate("a <= b;"); 2558b6301a01Ssstwcw ASSERT_EQ(Tokens.size(), 5u) << Tokens; 2559cad708b9Ssstwcw EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator); 2560cad708b9Ssstwcw EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment); 2561cad708b9Ssstwcw Tokens = Annotate("if (a <= b) break;"); 2562b6301a01Ssstwcw ASSERT_EQ(Tokens.size(), 9u) << Tokens; 2563cad708b9Ssstwcw EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator); 2564cad708b9Ssstwcw EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational); 2565cad708b9Ssstwcw Tokens = Annotate("a <= b <= a;"); 2566b6301a01Ssstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 2567cad708b9Ssstwcw EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator); 2568cad708b9Ssstwcw EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment); 2569cad708b9Ssstwcw EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator); 2570cad708b9Ssstwcw EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational); 257174cc4389Ssstwcw 257274cc4389Ssstwcw // Port lists in module instantiation. 257374cc4389Ssstwcw Tokens = Annotate("module_x instance_1(port_1), instance_2(port_2);"); 2574b6301a01Ssstwcw ASSERT_EQ(Tokens.size(), 12u) << Tokens; 257574cc4389Ssstwcw EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen); 257674cc4389Ssstwcw EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_VerilogInstancePortLParen); 257774cc4389Ssstwcw Tokens = Annotate("module_x #(parameter) instance_1(port_1), " 257874cc4389Ssstwcw "instance_2(port_2);"); 2579b6301a01Ssstwcw ASSERT_EQ(Tokens.size(), 16u) << Tokens; 258074cc4389Ssstwcw EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen); 258174cc4389Ssstwcw EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_VerilogInstancePortLParen); 258274cc4389Ssstwcw EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_VerilogInstancePortLParen); 25830571ba8dSsstwcw 25840571ba8dSsstwcw // Condition parentheses. 25850571ba8dSsstwcw Tokens = Annotate("assert (x);"); 25860571ba8dSsstwcw ASSERT_EQ(Tokens.size(), 6u) << Tokens; 25870571ba8dSsstwcw EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen); 25880571ba8dSsstwcw Tokens = Annotate("assert #0 (x);"); 25890571ba8dSsstwcw ASSERT_EQ(Tokens.size(), 8u) << Tokens; 25900571ba8dSsstwcw EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_ConditionLParen); 25910571ba8dSsstwcw Tokens = Annotate("assert final (x);"); 25920571ba8dSsstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 25930571ba8dSsstwcw EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen); 25940571ba8dSsstwcw Tokens = Annotate("foreach (x[x]) continue;"); 25950571ba8dSsstwcw ASSERT_EQ(Tokens.size(), 10u) << Tokens; 25960571ba8dSsstwcw EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen); 25970571ba8dSsstwcw Tokens = Annotate("repeat (x[x]) continue;"); 25980571ba8dSsstwcw ASSERT_EQ(Tokens.size(), 10u) << Tokens; 25990571ba8dSsstwcw EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen); 26000571ba8dSsstwcw Tokens = Annotate("case (x) endcase;"); 26010571ba8dSsstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 26020571ba8dSsstwcw EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen); 2603e1242855Ssstwcw 2604e1242855Ssstwcw // Sensitivity list. The TT_Unknown type is clearly not binding for the 2605e1242855Ssstwcw // future, please adapt if those tokens get annotated. This test is only here 2606e1242855Ssstwcw // to prevent the comma from being annotated as TT_VerilogInstancePortComma. 2607e1242855Ssstwcw Tokens = Annotate("always @(posedge x, posedge y);"); 2608e1242855Ssstwcw ASSERT_EQ(Tokens.size(), 11u) << Tokens; 2609e1242855Ssstwcw EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown); 2610e1242855Ssstwcw EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown); 2611e1242855Ssstwcw EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown); 2612ddc80637Ssstwcw 2613ddc80637Ssstwcw // String literals in concatenation. 2614ddc80637Ssstwcw Tokens = Annotate("x = {\"\"};"); 2615ddc80637Ssstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 2616ddc80637Ssstwcw EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation); 2617ddc80637Ssstwcw Tokens = Annotate("x = {\"\", \"\"};"); 2618ddc80637Ssstwcw ASSERT_EQ(Tokens.size(), 9u) << Tokens; 2619ddc80637Ssstwcw EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation); 2620ddc80637Ssstwcw EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation); 2621ddc80637Ssstwcw Tokens = Annotate("x = '{{\"\"}};"); 2622ddc80637Ssstwcw ASSERT_EQ(Tokens.size(), 10u) << Tokens; 2623ddc80637Ssstwcw EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation); 2624ddc80637Ssstwcw // Cases where the string should not be annotated that type. Fix the 2625ddc80637Ssstwcw // `TT_Unknown` if needed in the future. 2626ddc80637Ssstwcw Tokens = Annotate("x = {\"\" == \"\"};"); 2627ddc80637Ssstwcw ASSERT_EQ(Tokens.size(), 9u) << Tokens; 2628ddc80637Ssstwcw EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown); 2629ddc80637Ssstwcw EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown); 2630ddc80637Ssstwcw Tokens = Annotate("x = {(\"\")};"); 2631ddc80637Ssstwcw ASSERT_EQ(Tokens.size(), 9u) << Tokens; 2632ddc80637Ssstwcw EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown); 2633ddc80637Ssstwcw Tokens = Annotate("x = '{\"\"};"); 2634ddc80637Ssstwcw ASSERT_EQ(Tokens.size(), 8u) << Tokens; 2635ddc80637Ssstwcw EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown); 26360ff8b791Ssstwcw 26370ff8b791Ssstwcw // Module headers. 2638aa2d084fSOwen Pan Tokens = Annotate("module x();\n" 2639aa2d084fSOwen Pan "endmodule"); 26400ff8b791Ssstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 26410ff8b791Ssstwcw EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogMultiLineListLParen); 2642aa2d084fSOwen Pan Tokens = Annotate("function automatic `x x();\n" 2643aa2d084fSOwen Pan "endmodule"); 26440ff8b791Ssstwcw ASSERT_EQ(Tokens.size(), 10u) << Tokens; 26450ff8b791Ssstwcw EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_VerilogMultiLineListLParen); 2646aa2d084fSOwen Pan Tokens = Annotate("function automatic x``x x();\n" 2647aa2d084fSOwen Pan "endmodule"); 26480ff8b791Ssstwcw ASSERT_EQ(Tokens.size(), 11u) << Tokens; 26490ff8b791Ssstwcw EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_VerilogMultiLineListLParen); 2650aa2d084fSOwen Pan Tokens = Annotate("function automatic x::x x();\n" 2651aa2d084fSOwen Pan "endmodule"); 26520ff8b791Ssstwcw ASSERT_EQ(Tokens.size(), 11u) << Tokens; 26530ff8b791Ssstwcw EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_VerilogMultiLineListLParen); 2654fbef1f83Ssstwcw 2655fbef1f83Ssstwcw // Escaped identifiers. 2656fbef1f83Ssstwcw Tokens = Annotate(R"(\busa+index)"); 2657fbef1f83Ssstwcw ASSERT_EQ(Tokens.size(), 2u) << Tokens; 2658fbef1f83Ssstwcw EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown); 2659fbef1f83Ssstwcw Tokens = Annotate(R"(\busa+index ;)"); 2660fbef1f83Ssstwcw ASSERT_EQ(Tokens.size(), 3u) << Tokens; 2661fbef1f83Ssstwcw EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown); 2662fbef1f83Ssstwcw EXPECT_EQ(Tokens[0]->TokenText, R"(\busa+index)"); 2663fbef1f83Ssstwcw EXPECT_TOKEN(Tokens[1], tok::semi, TT_Unknown); 2664fbef1f83Ssstwcw Tokens = Annotate(R"(\busa+index 2665fbef1f83Ssstwcw ;)"); 2666fbef1f83Ssstwcw ASSERT_EQ(Tokens.size(), 3u) << Tokens; 2667fbef1f83Ssstwcw EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown); 2668fbef1f83Ssstwcw EXPECT_TOKEN(Tokens[1], tok::semi, TT_Unknown); 2669fbef1f83Ssstwcw // The escaped identifier can be broken by an escaped newline. The result is 2670fbef1f83Ssstwcw // still 1 identifier. 2671fbef1f83Ssstwcw Tokens = Annotate(R"(\busa+index\ 2672fbef1f83Ssstwcw + 2673fbef1f83Ssstwcw ;)"); 2674fbef1f83Ssstwcw ASSERT_EQ(Tokens.size(), 3u) << Tokens; 2675fbef1f83Ssstwcw EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown); 2676fbef1f83Ssstwcw EXPECT_EQ(Tokens[0]->TokenText, R"(\busa+index\ 2677fbef1f83Ssstwcw +)"); 2678fbef1f83Ssstwcw EXPECT_TOKEN(Tokens[1], tok::semi, TT_Unknown); 2679fbef1f83Ssstwcw // An escaped newline should not be treated as an escaped identifier. 2680fbef1f83Ssstwcw Tokens = Annotate("\\\n"); 2681fbef1f83Ssstwcw ASSERT_EQ(Tokens.size(), 1u) << Tokens; 2682fbef1f83Ssstwcw EXPECT_TOKEN(Tokens[0], tok::eof, TT_Unknown); 2683fbef1f83Ssstwcw // Macros. 2684fbef1f83Ssstwcw Tokens = Annotate("`define x x``x"); 2685fbef1f83Ssstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 2686fbef1f83Ssstwcw EXPECT_TOKEN(Tokens[0], tok::hash, TT_Unknown); 2687fbef1f83Ssstwcw EXPECT_TOKEN(Tokens[4], tok::hashhash, TT_Unknown); 2688f93182a8Ssstwcw } 2689f93182a8Ssstwcw 26900cc31579SHirofumi Nakamura TEST_F(TokenAnnotatorTest, UnderstandTableGenTokens) { 26910cc31579SHirofumi Nakamura auto Style = getLLVMStyle(FormatStyle::LK_TableGen); 26920cc31579SHirofumi Nakamura ASSERT_TRUE(Style.isTableGen()); 26930cc31579SHirofumi Nakamura 26940cc31579SHirofumi Nakamura TestLexer Lexer(Allocator, Buffers, Style); 26950cc31579SHirofumi Nakamura AdditionalKeywords Keywords(Lexer.IdentTable); 26961c58208dSOwen Pan auto Annotate = [&Lexer](StringRef Code) { return Lexer.annotate(Code); }; 26970cc31579SHirofumi Nakamura 26980cc31579SHirofumi Nakamura // Additional keywords representation test. 26990cc31579SHirofumi Nakamura auto Tokens = Annotate("def foo : Bar<1>;"); 27000cc31579SHirofumi Nakamura ASSERT_TRUE(Keywords.isTableGenKeyword(*Tokens[0])); 27010cc31579SHirofumi Nakamura ASSERT_TRUE(Keywords.isTableGenDefinition(*Tokens[0])); 27020cc31579SHirofumi Nakamura ASSERT_TRUE(Tokens[0]->is(Keywords.kw_def)); 27030cc31579SHirofumi Nakamura ASSERT_TRUE(Tokens[1]->is(TT_StartOfName)); 2704e3702f62SHirofumi Nakamura 2705e3702f62SHirofumi Nakamura // Code, the multiline string token. 2706e3702f62SHirofumi Nakamura Tokens = Annotate("[{ code is multiline string }]"); 2707e3702f62SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 2u) << Tokens; 2708e3702f62SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::string_literal, TT_TableGenMultiLineString); 2709e3702f62SHirofumi Nakamura EXPECT_FALSE(Tokens[0]->IsMultiline); 2710e3702f62SHirofumi Nakamura // Case with multiple lines. 2711e3702f62SHirofumi Nakamura Tokens = Annotate("[{ It can break\n" 2712e3702f62SHirofumi Nakamura " across lines and the line breaks\n" 2713e3702f62SHirofumi Nakamura " are retained in \n" 2714e3702f62SHirofumi Nakamura " the string. }]"); 2715e3702f62SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 2u) << Tokens; 2716e3702f62SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::string_literal, TT_TableGenMultiLineString); 2717e3702f62SHirofumi Nakamura EXPECT_EQ(Tokens[0]->ColumnWidth, sizeof("[{ It can break\n") - 1); 2718e3702f62SHirofumi Nakamura EXPECT_TRUE(Tokens[0]->IsMultiline); 2719e3702f62SHirofumi Nakamura EXPECT_EQ(Tokens[0]->LastLineColumnWidth, sizeof(" the string. }]") - 1); 2720fcb6737fSHirofumi Nakamura 272100582636SHirofumi Nakamura // Numeric literals. 272200582636SHirofumi Nakamura Tokens = Annotate("1234"); 272300582636SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::numeric_constant, TT_Unknown); 272400582636SHirofumi Nakamura Tokens = Annotate("-1"); 272500582636SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::numeric_constant, TT_Unknown); 272600582636SHirofumi Nakamura Tokens = Annotate("+1234"); 272700582636SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::numeric_constant, TT_Unknown); 272800582636SHirofumi Nakamura Tokens = Annotate("0b0110"); 272900582636SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::numeric_constant, TT_Unknown); 273000582636SHirofumi Nakamura Tokens = Annotate("0x1abC"); 273100582636SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::numeric_constant, TT_Unknown); 273200582636SHirofumi Nakamura 2733fcb6737fSHirofumi Nakamura // Identifier tokens. In TableGen, identifiers can begin with a number. 2734fcb6737fSHirofumi Nakamura // In ambiguous cases, the lexer tries to lex it as a number. 2735fcb6737fSHirofumi Nakamura // Even if the try fails, it does not fall back to identifier lexing and 2736fcb6737fSHirofumi Nakamura // regard as an error. 2737fcb6737fSHirofumi Nakamura // The ambiguity is not documented. The result of those tests are based on the 2738fcb6737fSHirofumi Nakamura // implementation of llvm::TGLexer::LexToken. 2739fcb6737fSHirofumi Nakamura // This is invalid syntax of number, but not an identifier. 2740fcb6737fSHirofumi Nakamura Tokens = Annotate("0x1234x"); 2741fcb6737fSHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::numeric_constant, TT_Unknown); 2742fcb6737fSHirofumi Nakamura Tokens = Annotate("identifier"); 2743fcb6737fSHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown); 2744fcb6737fSHirofumi Nakamura // Identifier beginning with a number. 2745fcb6737fSHirofumi Nakamura Tokens = Annotate("0x"); 2746fcb6737fSHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown); 2747fcb6737fSHirofumi Nakamura Tokens = Annotate("2dVector"); 2748fcb6737fSHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown); 2749fcb6737fSHirofumi Nakamura Tokens = Annotate("01234Vector"); 2750fcb6737fSHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown); 2751df4ba00cSHirofumi Nakamura 2752df4ba00cSHirofumi Nakamura // Structured statements. 2753df4ba00cSHirofumi Nakamura Tokens = Annotate("class Foo {}"); 2754df4ba00cSHirofumi Nakamura EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_FunctionLBrace); 2755df4ba00cSHirofumi Nakamura Tokens = Annotate("def Def: Foo {}"); 2756df4ba00cSHirofumi Nakamura EXPECT_TOKEN(Tokens[2], tok::colon, TT_InheritanceColon); 2757df4ba00cSHirofumi Nakamura EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace); 2758df4ba00cSHirofumi Nakamura Tokens = Annotate("if cond then {} else {}"); 2759df4ba00cSHirofumi Nakamura EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_ControlStatementLBrace); 2760df4ba00cSHirofumi Nakamura EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_ElseLBrace); 2761df4ba00cSHirofumi Nakamura Tokens = Annotate("defset Foo Def2 = {}"); 2762df4ba00cSHirofumi Nakamura EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace); 276300582636SHirofumi Nakamura 276400582636SHirofumi Nakamura // Bang Operators. 276500582636SHirofumi Nakamura Tokens = Annotate("!foreach"); 276600582636SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::identifier, TT_TableGenBangOperator); 276700582636SHirofumi Nakamura Tokens = Annotate("!if"); 276800582636SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::identifier, TT_TableGenBangOperator); 276900582636SHirofumi Nakamura Tokens = Annotate("!cond"); 277000582636SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::identifier, TT_TableGenCondOperator); 27716a471611SHirofumi Nakamura 27721c58208dSOwen Pan auto AnnotateValue = [this, &Style](StringRef Code) { 27736a471611SHirofumi Nakamura // Values are annotated only in specific context. 27746a471611SHirofumi Nakamura auto Result = annotate(("def X { let V = " + Code + "; }").str(), Style); 27756a471611SHirofumi Nakamura return decltype(Result){Result.begin() + 6, Result.end() - 3}; 27766a471611SHirofumi Nakamura }; 27776a471611SHirofumi Nakamura // Both of bang/cond operators. 27786a471611SHirofumi Nakamura Tokens = AnnotateValue("!cond(!eq(x, 0): 1, true: x)"); 27796a471611SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 15u) << Tokens; 27806a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::identifier, TT_TableGenCondOperator); 27816a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[2], tok::identifier, TT_TableGenBangOperator); 27826a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[8], tok::colon, TT_TableGenCondOperatorColon); 27836a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[10], tok::comma, TT_TableGenCondOperatorComma); 27846a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[12], tok::colon, TT_TableGenCondOperatorColon); 27856a471611SHirofumi Nakamura // DAGArg values with operator identifier 27866a471611SHirofumi Nakamura Tokens = AnnotateValue("(ins type1:$src1, type2:$src2)"); 27876a471611SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 10u) << Tokens; 27886a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpener); 27896a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[3], tok::colon, TT_TableGenDAGArgListColon); 27906a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[4], tok::identifier, TT_Unknown); // $src1 27916a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListComma); 27926a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[7], tok::colon, TT_TableGenDAGArgListColon); 27936a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); 27946a471611SHirofumi Nakamura // List literal 27956a471611SHirofumi Nakamura Tokens = AnnotateValue("[1, 2, 3]"); 27966a471611SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 7u) << Tokens; 27976a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::l_square, TT_TableGenListOpener); 27986a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[6], tok::r_square, TT_TableGenListCloser); 27996a471611SHirofumi Nakamura // Suffixes of values 28006a471611SHirofumi Nakamura Tokens = AnnotateValue("valid.field"); 28016a471611SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 3u) << Tokens; 28026a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[1], tok::period, TT_TableGenValueSuffix); 28036a471611SHirofumi Nakamura // Code 28046a471611SHirofumi Nakamura Tokens = AnnotateValue("[{ code is multiline string }]"); 28056a471611SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 1u) << Tokens; 28066a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::string_literal, TT_TableGenMultiLineString); 28076a471611SHirofumi Nakamura 28086a471611SHirofumi Nakamura // The definition 28096a471611SHirofumi Nakamura Tokens = annotate("def Def : Parent<Child> {}", Style); 28106a471611SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 10u) << Tokens; // This contains eof. 28116a471611SHirofumi Nakamura // We use inheritance colon and function brace. They are enough. 28126a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[2], tok::colon, TT_InheritanceColon); 28136a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[4], tok::less, TT_TemplateOpener); 28146a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[6], tok::greater, TT_TemplateCloser); 28156a471611SHirofumi Nakamura EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_FunctionLBrace); 28160c423af5SHirofumi Nakamura 28170c423af5SHirofumi Nakamura // DAGArg breaking options. They use different token types depending on what 28180c423af5SHirofumi Nakamura // is specified. 28190c423af5SHirofumi Nakamura Style.TableGenBreakInsideDAGArg = FormatStyle::DAS_BreakElements; 28200c423af5SHirofumi Nakamura 28210c423af5SHirofumi Nakamura // When TableGenBreakInsideDAGArg is DAS_BreakElements and 28220c423af5SHirofumi Nakamura // TableGenBreakingDAGArgOperators is not specified, it makes all the DAGArg 28230c423af5SHirofumi Nakamura // elements to have line break. 28240c423af5SHirofumi Nakamura Tokens = AnnotateValue("(ins type1:$src1, type2:$src2)"); 28250c423af5SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 10u) << Tokens; 28260c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); 28270c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[1], tok::identifier, 28280c423af5SHirofumi Nakamura TT_TableGenDAGArgOperatorID); // ins 28290c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListCommaToBreak); 28300c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); 28310c423af5SHirofumi Nakamura 28320c423af5SHirofumi Nakamura Tokens = AnnotateValue("(other type1:$src1, type2:$src2)"); 28330c423af5SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 10u) << Tokens; 28340c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); 28350c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[1], tok::identifier, 28360c423af5SHirofumi Nakamura TT_TableGenDAGArgOperatorID); // other 28370c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListCommaToBreak); 28380c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); 28390c423af5SHirofumi Nakamura 28400c423af5SHirofumi Nakamura // For non-identifier operators, breaks after the operator. 28410c423af5SHirofumi Nakamura Tokens = AnnotateValue("(!cast<Type>(\"Name\") type1:$src1, type2:$src2)"); 28420c423af5SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 16u) << Tokens; 28430c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); 28440c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_TableGenDAGArgOperatorToBreak); 28450c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[11], tok::comma, TT_TableGenDAGArgListCommaToBreak); 28460c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[15], tok::r_paren, TT_TableGenDAGArgCloser); 28470c423af5SHirofumi Nakamura 28480c423af5SHirofumi Nakamura Style.TableGenBreakInsideDAGArg = FormatStyle::DAS_BreakAll; 28490c423af5SHirofumi Nakamura 28500c423af5SHirofumi Nakamura // When TableGenBreakInsideDAGArg is DAS_BreakAll and 28510c423af5SHirofumi Nakamura // TableGenBreakingDAGArgOperators is not specified, it makes all the DAGArg 28520c423af5SHirofumi Nakamura // to have line break inside it. 28530c423af5SHirofumi Nakamura Tokens = AnnotateValue("(ins type1:$src1, type2:$src2)"); 28540c423af5SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 10u) << Tokens; 28550c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); 28560c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[1], tok::identifier, 28570c423af5SHirofumi Nakamura TT_TableGenDAGArgOperatorToBreak); // ins 28580c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListCommaToBreak); 28590c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); 28600c423af5SHirofumi Nakamura 28610c423af5SHirofumi Nakamura Tokens = AnnotateValue("(other type1:$src1, type2:$src2)"); 28620c423af5SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 10u) << Tokens; 28630c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); 28640c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[1], tok::identifier, 28650c423af5SHirofumi Nakamura TT_TableGenDAGArgOperatorToBreak); // other 28660c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListCommaToBreak); 28670c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); 28680c423af5SHirofumi Nakamura 28690c423af5SHirofumi Nakamura // If TableGenBreakingDAGArgOperators is specified, it is limited to the 28700c423af5SHirofumi Nakamura // specified operators. 28710c423af5SHirofumi Nakamura Style.TableGenBreakingDAGArgOperators = {"ins", "outs"}; 28720c423af5SHirofumi Nakamura Tokens = AnnotateValue("(ins type1:$src1, type2:$src2)"); 28730c423af5SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 10u) << Tokens; 28740c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); 28750c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[1], tok::identifier, 28760c423af5SHirofumi Nakamura TT_TableGenDAGArgOperatorToBreak); // ins 28770c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListCommaToBreak); 28780c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); 28790c423af5SHirofumi Nakamura 28800c423af5SHirofumi Nakamura Tokens = AnnotateValue("(other type1:$src1, type2:$src2)"); 28810c423af5SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 10u) << Tokens; 28820c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpener); 28830c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[1], tok::identifier, TT_Unknown); // other 28840c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListComma); 28850c423af5SHirofumi Nakamura EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); 2886e54af608SHirofumi Nakamura 2887e54af608SHirofumi Nakamura // If TableGenBreakingDAGArgOperators is enabled, it uses 2888e54af608SHirofumi Nakamura // TT_TableGenDAGArgListColonToAlign to annotate the colon to align. 2889e54af608SHirofumi Nakamura Style.AlignConsecutiveTableGenBreakingDAGArgColons.Enabled = true; 2890e54af608SHirofumi Nakamura Tokens = AnnotateValue("(ins type1:$src1, type2:$src2)"); 2891e54af608SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 10u) << Tokens; 2892e54af608SHirofumi Nakamura EXPECT_TOKEN(Tokens[1], tok::identifier, 2893e54af608SHirofumi Nakamura TT_TableGenDAGArgOperatorToBreak); // ins 2894e54af608SHirofumi Nakamura EXPECT_TOKEN(Tokens[3], tok::colon, TT_TableGenDAGArgListColonToAlign); 2895e54af608SHirofumi Nakamura EXPECT_TOKEN(Tokens[7], tok::colon, TT_TableGenDAGArgListColonToAlign); 2896e54af608SHirofumi Nakamura 2897e54af608SHirofumi Nakamura Tokens = AnnotateValue("(other type1:$src1, type2:$src2)"); 2898e54af608SHirofumi Nakamura ASSERT_EQ(Tokens.size(), 10u) << Tokens; 2899e54af608SHirofumi Nakamura EXPECT_TOKEN(Tokens[1], tok::identifier, TT_Unknown); // other 2900e54af608SHirofumi Nakamura EXPECT_TOKEN(Tokens[3], tok::colon, TT_TableGenDAGArgListColon); 2901e54af608SHirofumi Nakamura EXPECT_TOKEN(Tokens[7], tok::colon, TT_TableGenDAGArgListColon); 29020cc31579SHirofumi Nakamura } 29030cc31579SHirofumi Nakamura 2904f97639ceSBjörn Schäpers TEST_F(TokenAnnotatorTest, UnderstandConstructors) { 2905f97639ceSBjörn Schäpers auto Tokens = annotate("Class::Class() : BaseClass(), Member() {}"); 2906f97639ceSBjörn Schäpers 2907f97639ceSBjörn Schäpers // The TT_Unknown is clearly not binding for the future, please adapt if those 2908f97639ceSBjörn Schäpers // tokens get annotated. 2909f97639ceSBjörn Schäpers ASSERT_EQ(Tokens.size(), 16u) << Tokens; 2910f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[5], tok::colon, TT_CtorInitializerColon); 2911f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[6], tok::identifier, TT_Unknown); 2912f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_Unknown); 2913f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown); 2914f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[9], tok::comma, TT_CtorInitializerComma); 2915f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[10], tok::identifier, TT_Unknown); 2916f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_Unknown); 2917f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[12], tok::r_paren, TT_Unknown); 2918f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_FunctionLBrace); 2919063e3fe6SEmilia Kond EXPECT_BRACE_KIND(Tokens[13], BK_Block); 2920f97639ceSBjörn Schäpers 2921f97639ceSBjörn Schäpers Tokens = annotate("Class::Class() : BaseClass{}, Member{} {}"); 2922f97639ceSBjörn Schäpers ASSERT_EQ(Tokens.size(), 16u) << Tokens; 2923f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[5], tok::colon, TT_CtorInitializerColon); 2924f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[6], tok::identifier, TT_Unknown); 2925f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_Unknown); 2926f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[8], tok::r_brace, TT_Unknown); 2927f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[9], tok::comma, TT_CtorInitializerComma); 2928f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[10], tok::identifier, TT_Unknown); 2929f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_Unknown); 2930f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[12], tok::r_brace, TT_Unknown); 2931f97639ceSBjörn Schäpers EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_FunctionLBrace); 2932063e3fe6SEmilia Kond EXPECT_BRACE_KIND(Tokens[13], BK_Block); 2933063e3fe6SEmilia Kond 2934063e3fe6SEmilia Kond Tokens = annotate("class Class {\n" 2935063e3fe6SEmilia Kond " Class() : BaseClass() {\n" 2936063e3fe6SEmilia Kond "#if 0\n" 2937063e3fe6SEmilia Kond " // comment\n" 2938063e3fe6SEmilia Kond "#endif\n" 2939063e3fe6SEmilia Kond " }\n" 2940063e3fe6SEmilia Kond " Class f();\n" 2941063e3fe6SEmilia Kond "}"); 2942063e3fe6SEmilia Kond ASSERT_EQ(Tokens.size(), 25u) << Tokens; 2943063e3fe6SEmilia Kond EXPECT_TOKEN(Tokens[6], tok::colon, TT_CtorInitializerColon); 2944063e3fe6SEmilia Kond EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_FunctionLBrace); 2945063e3fe6SEmilia Kond EXPECT_BRACE_KIND(Tokens[10], BK_Block); 2946f97639ceSBjörn Schäpers } 2947f97639ceSBjörn Schäpers 29480571ba8dSsstwcw TEST_F(TokenAnnotatorTest, UnderstandsConditionParens) { 29490571ba8dSsstwcw auto Tokens = annotate("if (x) {}"); 29500571ba8dSsstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 29510571ba8dSsstwcw EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen); 29520571ba8dSsstwcw Tokens = annotate("if constexpr (x) {}"); 29530571ba8dSsstwcw ASSERT_EQ(Tokens.size(), 8u) << Tokens; 29540571ba8dSsstwcw EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen); 29550571ba8dSsstwcw Tokens = annotate("if CONSTEXPR (x) {}"); 29560571ba8dSsstwcw ASSERT_EQ(Tokens.size(), 8u) << Tokens; 29570571ba8dSsstwcw EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen); 29580571ba8dSsstwcw Tokens = annotate("if (x) {} else if (x) {}"); 29590571ba8dSsstwcw ASSERT_EQ(Tokens.size(), 14u) << Tokens; 29600571ba8dSsstwcw EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen); 29610571ba8dSsstwcw EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_ConditionLParen); 29620571ba8dSsstwcw } 29630571ba8dSsstwcw 2964799b794dSmydeveloperday TEST_F(TokenAnnotatorTest, CSharpNullableTypes) { 2965799b794dSmydeveloperday FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 2966799b794dSmydeveloperday 2967799b794dSmydeveloperday auto Tokens = annotate("int? a;", Style); 296888d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 5u) << Tokens; 2969799b794dSmydeveloperday EXPECT_TOKEN(Tokens[1], tok::question, TT_CSharpNullable); 2970799b794dSmydeveloperday 2971799b794dSmydeveloperday Tokens = annotate("int? a = 1;", Style); 297288d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 7u) << Tokens; 2973799b794dSmydeveloperday EXPECT_TOKEN(Tokens[1], tok::question, TT_CSharpNullable); 2974799b794dSmydeveloperday 2975799b794dSmydeveloperday Tokens = annotate("int?)", Style); 297688d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 4u) << Tokens; 2977799b794dSmydeveloperday EXPECT_TOKEN(Tokens[1], tok::question, TT_CSharpNullable); 2978799b794dSmydeveloperday 2979799b794dSmydeveloperday Tokens = annotate("int?>", Style); 298088d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 4u) << Tokens; 2981799b794dSmydeveloperday EXPECT_TOKEN(Tokens[1], tok::question, TT_CSharpNullable); 2982799b794dSmydeveloperday 2983799b794dSmydeveloperday Tokens = annotate("cond? id : id2", Style); 298488d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 6u) << Tokens; 2985799b794dSmydeveloperday EXPECT_TOKEN(Tokens[1], tok::question, TT_ConditionalExpr); 2986799b794dSmydeveloperday 2987799b794dSmydeveloperday Tokens = annotate("cond ? cond2 ? : id1 : id2", Style); 298888d1de5eSEmilia Kond ASSERT_EQ(Tokens.size(), 9u) << Tokens; 2989799b794dSmydeveloperday EXPECT_TOKEN(Tokens[1], tok::question, TT_ConditionalExpr); 2990799b794dSmydeveloperday } 2991799b794dSmydeveloperday 299282a90caaSsstwcw TEST_F(TokenAnnotatorTest, UnderstandsLabels) { 299382a90caaSsstwcw auto Tokens = annotate("{ x: break; }"); 299482a90caaSsstwcw ASSERT_EQ(Tokens.size(), 7u) << Tokens; 299582a90caaSsstwcw EXPECT_TOKEN(Tokens[2], tok::colon, TT_GotoLabelColon); 2996d89f2005SOwen Pan 299782a90caaSsstwcw Tokens = annotate("{ case x: break; }"); 299882a90caaSsstwcw ASSERT_EQ(Tokens.size(), 8u) << Tokens; 299982a90caaSsstwcw EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon); 3000d89f2005SOwen Pan 300182a90caaSsstwcw Tokens = annotate("{ x: { break; } }"); 300282a90caaSsstwcw ASSERT_EQ(Tokens.size(), 9u) << Tokens; 300382a90caaSsstwcw EXPECT_TOKEN(Tokens[2], tok::colon, TT_GotoLabelColon); 3004d89f2005SOwen Pan 300582a90caaSsstwcw Tokens = annotate("{ case x: { break; } }"); 300682a90caaSsstwcw ASSERT_EQ(Tokens.size(), 10u) << Tokens; 300782a90caaSsstwcw EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon); 3008d89f2005SOwen Pan 3009d89f2005SOwen Pan Tokens = annotate("#define FOO label:"); 3010d89f2005SOwen Pan ASSERT_EQ(Tokens.size(), 6u) << Tokens; 3011d89f2005SOwen Pan EXPECT_TOKEN(Tokens[4], tok::colon, TT_GotoLabelColon); 3012d89f2005SOwen Pan 3013d89f2005SOwen Pan Tokens = annotate("#define FOO \\\n" 3014d89f2005SOwen Pan "label: \\\n" 3015d89f2005SOwen Pan " break;"); 3016d89f2005SOwen Pan ASSERT_EQ(Tokens.size(), 8u) << Tokens; 3017d89f2005SOwen Pan EXPECT_TOKEN(Tokens[4], tok::colon, TT_GotoLabelColon); 301882a90caaSsstwcw } 301982a90caaSsstwcw 3020d39929b9SGalen Elias TEST_F(TokenAnnotatorTest, UnderstandsNestedBlocks) { 3021d39929b9SGalen Elias // The closing braces are not annotated. It doesn't seem to cause a problem. 3022d39929b9SGalen Elias // So we only test for the opening braces. 3023d39929b9SGalen Elias auto Tokens = annotate("{\n" 3024d39929b9SGalen Elias " {\n" 3025d39929b9SGalen Elias " { int a = 0; }\n" 3026d39929b9SGalen Elias " }\n" 3027d39929b9SGalen Elias " {}\n" 3028d39929b9SGalen Elias "}"); 3029d39929b9SGalen Elias ASSERT_EQ(Tokens.size(), 14u) << Tokens; 3030d39929b9SGalen Elias EXPECT_BRACE_KIND(Tokens[0], BK_Block); 3031d39929b9SGalen Elias EXPECT_BRACE_KIND(Tokens[1], BK_Block); 3032d39929b9SGalen Elias EXPECT_BRACE_KIND(Tokens[2], BK_Block); 3033d39929b9SGalen Elias EXPECT_BRACE_KIND(Tokens[10], BK_Block); 3034d39929b9SGalen Elias } 3035d39929b9SGalen Elias 3036e9ed1aa9SEmilia Kond TEST_F(TokenAnnotatorTest, UnderstandDesignatedInitializers) { 3037e9ed1aa9SEmilia Kond auto Tokens = annotate("SomeStruct { .a = 1 };"); 3038e9ed1aa9SEmilia Kond ASSERT_EQ(Tokens.size(), 9u) << Tokens; 3039e9ed1aa9SEmilia Kond EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit); 3040e9ed1aa9SEmilia Kond EXPECT_TOKEN(Tokens[2], tok::period, TT_DesignatedInitializerPeriod); 3041e9ed1aa9SEmilia Kond 3042e9ed1aa9SEmilia Kond Tokens = annotate("SomeStruct { .a = 1, .b = 2 };"); 3043e9ed1aa9SEmilia Kond ASSERT_EQ(Tokens.size(), 14u) << Tokens; 3044e9ed1aa9SEmilia Kond EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit); 3045e9ed1aa9SEmilia Kond EXPECT_TOKEN(Tokens[2], tok::period, TT_DesignatedInitializerPeriod); 3046e9ed1aa9SEmilia Kond EXPECT_TOKEN(Tokens[7], tok::period, TT_DesignatedInitializerPeriod); 3047e9ed1aa9SEmilia Kond 3048e9ed1aa9SEmilia Kond Tokens = annotate("SomeStruct {\n" 3049e9ed1aa9SEmilia Kond "#ifdef FOO\n" 3050e9ed1aa9SEmilia Kond " .a = 1,\n" 3051e9ed1aa9SEmilia Kond "#endif\n" 3052e9ed1aa9SEmilia Kond " .b = 2\n" 3053e9ed1aa9SEmilia Kond "};"); 3054e9ed1aa9SEmilia Kond ASSERT_EQ(Tokens.size(), 19u) << Tokens; 3055e9ed1aa9SEmilia Kond EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit); 3056e9ed1aa9SEmilia Kond EXPECT_TOKEN(Tokens[5], tok::period, TT_DesignatedInitializerPeriod); 3057e9ed1aa9SEmilia Kond EXPECT_TOKEN(Tokens[12], tok::period, TT_DesignatedInitializerPeriod); 3058e9ed1aa9SEmilia Kond 3059e9ed1aa9SEmilia Kond Tokens = annotate("SomeStruct {\n" 3060e9ed1aa9SEmilia Kond "#if defined FOO\n" 3061e9ed1aa9SEmilia Kond " .a = 1,\n" 3062e9ed1aa9SEmilia Kond "#endif\n" 3063e9ed1aa9SEmilia Kond " .b = 2\n" 3064e9ed1aa9SEmilia Kond "};"); 3065e9ed1aa9SEmilia Kond ASSERT_EQ(Tokens.size(), 20u) << Tokens; 3066e9ed1aa9SEmilia Kond EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit); 3067e9ed1aa9SEmilia Kond EXPECT_TOKEN(Tokens[6], tok::period, TT_DesignatedInitializerPeriod); 3068e9ed1aa9SEmilia Kond EXPECT_TOKEN(Tokens[13], tok::period, TT_DesignatedInitializerPeriod); 3069093e6bddSXDeme 3070093e6bddSXDeme Tokens = annotate("Foo foo[] = {[0]{}};"); 3071093e6bddSXDeme ASSERT_EQ(Tokens.size(), 14u) << Tokens; 3072093e6bddSXDeme EXPECT_TOKEN(Tokens[6], tok::l_square, TT_DesignatedInitializerLSquare); 3073093e6bddSXDeme EXPECT_BRACE_KIND(Tokens[9], BK_BracedInit); 3074e9ed1aa9SEmilia Kond } 3075e9ed1aa9SEmilia Kond 30765db201fbSsstwcw TEST_F(TokenAnnotatorTest, UnderstandsJavaScript) { 30771c58208dSOwen Pan auto Annotate = [this](StringRef Code) { 30785db201fbSsstwcw return annotate(Code, getLLVMStyle(FormatStyle::LK_JavaScript)); 30795db201fbSsstwcw }; 30805db201fbSsstwcw 30815db201fbSsstwcw // Dictionary. 30825db201fbSsstwcw auto Tokens = Annotate("var x = {'x' : 1, 'y' : 2};"); 30835db201fbSsstwcw ASSERT_EQ(Tokens.size(), 14u) << Tokens; 30845db201fbSsstwcw EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_DictLiteral); 30855db201fbSsstwcw EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_SelectorName); 30865db201fbSsstwcw EXPECT_TOKEN(Tokens[5], tok::colon, TT_DictLiteral); 30875db201fbSsstwcw EXPECT_TOKEN(Tokens[8], tok::string_literal, TT_SelectorName); 30885db201fbSsstwcw EXPECT_TOKEN(Tokens[9], tok::colon, TT_DictLiteral); 30895db201fbSsstwcw // Change when we need to annotate these. 30905db201fbSsstwcw EXPECT_BRACE_KIND(Tokens[3], BK_Unknown); 30915db201fbSsstwcw EXPECT_BRACE_KIND(Tokens[11], BK_Unknown); 30925db201fbSsstwcw EXPECT_TOKEN(Tokens[11], tok::r_brace, TT_Unknown); 30935db201fbSsstwcw } 30945db201fbSsstwcw 3095cef9f40cSOwen Pan TEST_F(TokenAnnotatorTest, UnderstandsAttributes) { 3096cef9f40cSOwen Pan auto Tokens = annotate("bool foo __attribute__((unused));"); 3097cef9f40cSOwen Pan ASSERT_EQ(Tokens.size(), 10u) << Tokens; 3098a8528693SGedare Bloom EXPECT_TOKEN(Tokens[1], tok::identifier, TT_StartOfName); 3099cef9f40cSOwen Pan EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_AttributeLParen); 3100cef9f40cSOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_Unknown); 3101cef9f40cSOwen Pan EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_Unknown); 3102cef9f40cSOwen Pan EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_AttributeRParen); 3103151d0a4dSOwen Pan 3104151d0a4dSOwen Pan Tokens = annotate("bool foo __declspec(dllimport);"); 3105151d0a4dSOwen Pan ASSERT_EQ(Tokens.size(), 8u) << Tokens; 3106151d0a4dSOwen Pan EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_AttributeLParen); 3107151d0a4dSOwen Pan EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen); 3108151d0a4dSOwen Pan 3109a8528693SGedare Bloom Tokens = annotate("bool __attribute__((unused)) foo;"); 3110a8528693SGedare Bloom ASSERT_EQ(Tokens.size(), 10u) << Tokens; 3111a8528693SGedare Bloom EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_AttributeLParen); 3112a8528693SGedare Bloom EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_Unknown); 3113a8528693SGedare Bloom EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_Unknown); 3114a8528693SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_AttributeRParen); 3115a8528693SGedare Bloom EXPECT_TOKEN(Tokens[7], tok::identifier, TT_StartOfName); 3116a8528693SGedare Bloom 3117a8528693SGedare Bloom Tokens = annotate("void __attribute__((x)) Foo();"); 3118a8528693SGedare Bloom ASSERT_EQ(Tokens.size(), 12u) << Tokens; 3119a8528693SGedare Bloom EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_AttributeLParen); 3120a8528693SGedare Bloom EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_Unknown); 3121a8528693SGedare Bloom EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_Unknown); 3122a8528693SGedare Bloom EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_AttributeRParen); 3123a8528693SGedare Bloom EXPECT_TOKEN(Tokens[7], tok::identifier, TT_FunctionDeclarationName); 3124b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_FunctionDeclarationLParen); 3125a8528693SGedare Bloom 3126151d0a4dSOwen Pan FormatStyle Style = getLLVMStyle(); 3127151d0a4dSOwen Pan Style.AttributeMacros.push_back("FOO"); 3128151d0a4dSOwen Pan Tokens = annotate("bool foo FOO(unused);", Style); 3129151d0a4dSOwen Pan ASSERT_EQ(Tokens.size(), 8u) << Tokens; 3130151d0a4dSOwen Pan EXPECT_TOKEN(Tokens[2], tok::identifier, TT_AttributeMacro); 3131151d0a4dSOwen Pan EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_AttributeLParen); 3132151d0a4dSOwen Pan EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen); 3133cef9f40cSOwen Pan } 3134cef9f40cSOwen Pan 3135a8896e57SBjörn Schäpers TEST_F(TokenAnnotatorTest, UnderstandsControlStatements) { 3136a8896e57SBjörn Schäpers auto Tokens = annotate("while (true) {}"); 3137a8896e57SBjörn Schäpers ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3138a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_ControlStatementLBrace); 3139a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[5], tok::r_brace, TT_ControlStatementRBrace); 3140a8896e57SBjörn Schäpers 3141a8896e57SBjörn Schäpers Tokens = annotate("for (;;) {}"); 3142a8896e57SBjörn Schäpers ASSERT_EQ(Tokens.size(), 8u) << Tokens; 3143a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_ControlStatementLBrace); 3144a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[6], tok::r_brace, TT_ControlStatementRBrace); 3145a8896e57SBjörn Schäpers 3146a8896e57SBjörn Schäpers Tokens = annotate("do {} while (true);"); 3147a8896e57SBjörn Schäpers ASSERT_EQ(Tokens.size(), 9u) << Tokens; 3148a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_ControlStatementLBrace); 3149a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[2], tok::r_brace, TT_ControlStatementRBrace); 3150a8896e57SBjörn Schäpers 3151a8896e57SBjörn Schäpers Tokens = annotate("if (true) {} else if (false) {} else {}"); 3152a8896e57SBjörn Schäpers ASSERT_EQ(Tokens.size(), 17u) << Tokens; 3153a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_ControlStatementLBrace); 3154a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[5], tok::r_brace, TT_ControlStatementRBrace); 3155a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_ControlStatementLBrace); 3156a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[12], tok::r_brace, TT_ControlStatementRBrace); 3157a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[14], tok::l_brace, TT_ElseLBrace); 3158a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[15], tok::r_brace, TT_ElseRBrace); 3159a8896e57SBjörn Schäpers 3160a8896e57SBjörn Schäpers Tokens = annotate("switch (foo) {}"); 3161a8896e57SBjörn Schäpers ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3162a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_ControlStatementLBrace); 3163a8896e57SBjörn Schäpers EXPECT_TOKEN(Tokens[5], tok::r_brace, TT_ControlStatementRBrace); 3164a8896e57SBjörn Schäpers } 3165a8896e57SBjörn Schäpers 3166a95d4b79SBjörn Schäpers TEST_F(TokenAnnotatorTest, UnderstandsDoWhile) { 3167a95d4b79SBjörn Schäpers auto Tokens = annotate("do { ++i; } while ( i > 5 );"); 3168a95d4b79SBjörn Schäpers ASSERT_EQ(Tokens.size(), 14u) << Tokens; 3169a95d4b79SBjörn Schäpers EXPECT_TOKEN(Tokens[6], tok::kw_while, TT_DoWhile); 3170a95d4b79SBjörn Schäpers 3171a95d4b79SBjörn Schäpers Tokens = annotate("do ++i; while ( i > 5 );"); 3172a95d4b79SBjörn Schäpers ASSERT_EQ(Tokens.size(), 12u) << Tokens; 3173a95d4b79SBjörn Schäpers EXPECT_TOKEN(Tokens[4], tok::kw_while, TT_DoWhile); 3174a95d4b79SBjörn Schäpers } 3175a95d4b79SBjörn Schäpers 3176cb3a605cSOwen Pan TEST_F(TokenAnnotatorTest, StartOfName) { 3177eaff0830SOwen Pan auto Tokens = annotate("#pragma clang diagnostic push"); 3178eaff0830SOwen Pan ASSERT_EQ(Tokens.size(), 6u) << Tokens; 3179eaff0830SOwen Pan EXPECT_TOKEN(Tokens[2], tok::identifier, TT_Unknown); 3180eaff0830SOwen Pan EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown); 3181eaff0830SOwen Pan EXPECT_TOKEN(Tokens[4], tok::identifier, TT_Unknown); 3182eaff0830SOwen Pan 3183eaff0830SOwen Pan Tokens = annotate("#pragma clang diagnostic ignored \"-Wzero-length-array\""); 3184eaff0830SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3185eaff0830SOwen Pan EXPECT_TOKEN(Tokens[2], tok::identifier, TT_Unknown); 3186eaff0830SOwen Pan EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown); 3187eaff0830SOwen Pan EXPECT_TOKEN(Tokens[4], tok::identifier, TT_Unknown); 3188cb3a605cSOwen Pan 3189cb3a605cSOwen Pan Tokens = annotate("#define FOO Foo foo"); 3190cb3a605cSOwen Pan ASSERT_EQ(Tokens.size(), 6u) << Tokens; 3191cb3a605cSOwen Pan EXPECT_TOKEN(Tokens[2], tok::identifier, TT_Unknown); 3192cb3a605cSOwen Pan EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown); 3193cb3a605cSOwen Pan EXPECT_TOKEN(Tokens[4], tok::identifier, TT_StartOfName); 31947c460c62SOwen Pan 31957c460c62SOwen Pan Tokens = annotate("@interface NSCoder (TestCoder)"); 31967c460c62SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 31977c460c62SOwen Pan EXPECT_TOKEN(Tokens[0], tok::at, TT_ObjCDecl); 31987c460c62SOwen Pan EXPECT_TOKEN(Tokens[2], tok::identifier, TT_StartOfName); 3199dcebe297SOwen Pan 3200dcebe297SOwen Pan auto Style = getLLVMStyle(); 3201dcebe297SOwen Pan Style.StatementAttributeLikeMacros.push_back("emit"); 3202dcebe297SOwen Pan Tokens = annotate("emit foo = 0;", Style); 3203dcebe297SOwen Pan ASSERT_EQ(Tokens.size(), 6u) << Tokens; 3204dcebe297SOwen Pan EXPECT_TOKEN(Tokens[0], tok::identifier, TT_StatementAttributeLikeMacro); 3205dcebe297SOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_Unknown); 3206eaff0830SOwen Pan } 3207eaff0830SOwen Pan 3208edad025dSOwen Pan TEST_F(TokenAnnotatorTest, BraceKind) { 3209edad025dSOwen Pan auto Tokens = annotate("void f() {};"); 3210edad025dSOwen Pan ASSERT_EQ(Tokens.size(), 8u) << Tokens; 3211edad025dSOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 3212b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); 3213edad025dSOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace); 3214edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_Block); 3215edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[5], BK_Block); 3216edad025dSOwen Pan 3217a464e051SXDeme Tokens = annotate("class Foo<int> f() {}"); 3218a464e051SXDeme ASSERT_EQ(Tokens.size(), 11u) << Tokens; 3219a464e051SXDeme EXPECT_TOKEN(Tokens[5], tok::identifier, TT_FunctionDeclarationName); 3220b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionDeclarationLParen); 3221a464e051SXDeme EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_FunctionLBrace); 3222a464e051SXDeme EXPECT_BRACE_KIND(Tokens[8], BK_Block); 3223a464e051SXDeme EXPECT_BRACE_KIND(Tokens[9], BK_Block); 3224a464e051SXDeme 3225a464e051SXDeme Tokens = annotate("template <typename T> class Foo<T> f() {}"); 3226a464e051SXDeme ASSERT_EQ(Tokens.size(), 16u) << Tokens; 3227a464e051SXDeme EXPECT_TOKEN(Tokens[10], tok::identifier, TT_FunctionDeclarationName); 3228b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_FunctionDeclarationLParen); 3229a464e051SXDeme EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_FunctionLBrace); 3230a464e051SXDeme EXPECT_BRACE_KIND(Tokens[13], BK_Block); 3231a464e051SXDeme EXPECT_BRACE_KIND(Tokens[14], BK_Block); 3232a464e051SXDeme 3233edad025dSOwen Pan Tokens = annotate("void f() override {};"); 3234edad025dSOwen Pan ASSERT_EQ(Tokens.size(), 9u) << Tokens; 3235edad025dSOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 3236b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); 3237edad025dSOwen Pan EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_FunctionLBrace); 3238edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[5], BK_Block); 3239edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_Block); 3240edad025dSOwen Pan 3241edad025dSOwen Pan Tokens = annotate("void f() noexcept(false) {};"); 3242edad025dSOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 3243edad025dSOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 3244b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); 3245edad025dSOwen Pan EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_FunctionLBrace); 3246edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[8], BK_Block); 3247edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[9], BK_Block); 3248edad025dSOwen Pan 3249edad025dSOwen Pan Tokens = annotate("auto f() -> void {};"); 3250edad025dSOwen Pan ASSERT_EQ(Tokens.size(), 10u) << Tokens; 3251edad025dSOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 3252b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); 3253edad025dSOwen Pan EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_FunctionLBrace); 3254edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_Block); 3255edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[7], BK_Block); 3256edad025dSOwen Pan 3257edad025dSOwen Pan Tokens = annotate("void f() { /**/ };"); 3258edad025dSOwen Pan ASSERT_EQ(Tokens.size(), 9u) << Tokens; 3259edad025dSOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 3260b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); 3261edad025dSOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace); 3262edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_Block); 3263edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_Block); 3264edad025dSOwen Pan 3265edad025dSOwen Pan Tokens = annotate("void f() { //\n" 3266edad025dSOwen Pan "};"); 3267edad025dSOwen Pan ASSERT_EQ(Tokens.size(), 9u) << Tokens; 3268edad025dSOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 3269b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); 3270edad025dSOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace); 3271edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_Block); 3272edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_Block); 3273edad025dSOwen Pan 3274edad025dSOwen Pan Tokens = annotate("void f() {\n" 3275edad025dSOwen Pan " //\n" 3276edad025dSOwen Pan "};"); 3277edad025dSOwen Pan ASSERT_EQ(Tokens.size(), 9u) << Tokens; 3278edad025dSOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); 3279b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); 3280edad025dSOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace); 3281edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_Block); 3282edad025dSOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_Block); 32838de23009SOwen Pan 32848de23009SOwen Pan Tokens = annotate("struct Foo {\n" 32858de23009SOwen Pan " Foo() {};\n" 32868de23009SOwen Pan " ~Foo() {};\n" 32878de23009SOwen Pan "};"); 32888de23009SOwen Pan ASSERT_EQ(Tokens.size(), 19u) << Tokens; 32898de23009SOwen Pan EXPECT_TOKEN(Tokens[3], tok::identifier, TT_CtorDtorDeclName); 3290b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_FunctionDeclarationLParen); 32918de23009SOwen Pan EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_FunctionLBrace); 32928de23009SOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_Block); 32938de23009SOwen Pan EXPECT_BRACE_KIND(Tokens[7], BK_Block); 32948de23009SOwen Pan EXPECT_TOKEN(Tokens[10], tok::identifier, TT_CtorDtorDeclName); 3295b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_FunctionDeclarationLParen); 32968de23009SOwen Pan EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_FunctionLBrace); 32978de23009SOwen Pan EXPECT_BRACE_KIND(Tokens[13], BK_Block); 32988de23009SOwen Pan EXPECT_BRACE_KIND(Tokens[14], BK_Block); 32997c9c38eaSOwen Pan 33007c9c38eaSOwen Pan Tokens = annotate("{\n" 33017c9c38eaSOwen Pan " char *a[] = {\n" 33027c9c38eaSOwen Pan " /* abc */ \"abc\",\n" 33037c9c38eaSOwen Pan "#if FOO\n" 33047c9c38eaSOwen Pan " /* xyz */ \"xyz\",\n" 33057c9c38eaSOwen Pan "#endif\n" 33067c9c38eaSOwen Pan " /* last */ \"last\"};\n" 33077c9c38eaSOwen Pan "}"); 33087c9c38eaSOwen Pan ASSERT_EQ(Tokens.size(), 25u) << Tokens; 33097c9c38eaSOwen Pan EXPECT_BRACE_KIND(Tokens[0], BK_Block); 33107c9c38eaSOwen Pan EXPECT_BRACE_KIND(Tokens[7], BK_BracedInit); 33117c9c38eaSOwen Pan EXPECT_BRACE_KIND(Tokens[21], BK_BracedInit); 331258323de2SOwen Pan 331358323de2SOwen Pan Tokens = 331458323de2SOwen Pan annotate("#define SCOP_STAT(NAME, DESC) \\\n" 331558323de2SOwen Pan " {\"polly\", #NAME, \"Number of rejected regions: \" DESC}"); 331658323de2SOwen Pan ASSERT_EQ(Tokens.size(), 18u) << Tokens; 331758323de2SOwen Pan EXPECT_BRACE_KIND(Tokens[8], BK_BracedInit); 331858323de2SOwen Pan EXPECT_BRACE_KIND(Tokens[16], BK_BracedInit); 3319469c8a0aSOwen Pan 3320469c8a0aSOwen Pan Tokens = annotate("struct {};"); 3321469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 5u) << Tokens; 3322469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[1], BK_Block); 3323469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[2], BK_Block); 3324469c8a0aSOwen Pan 3325469c8a0aSOwen Pan Tokens = annotate("struct : Base {};"); 3326469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3327469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[3], BK_Block); 3328469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_Block); 3329469c8a0aSOwen Pan 3330469c8a0aSOwen Pan Tokens = annotate("struct Foo {};"); 3331469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 6u) << Tokens; 3332469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[2], BK_Block); 3333469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[3], BK_Block); 3334469c8a0aSOwen Pan 3335469c8a0aSOwen Pan Tokens = annotate("struct ::Foo {};"); 3336469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3337469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[3], BK_Block); 3338469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_Block); 3339469c8a0aSOwen Pan 3340469c8a0aSOwen Pan Tokens = annotate("struct NS::Foo {};"); 3341469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 8u) << Tokens; 3342469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_Block); 3343469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[5], BK_Block); 3344469c8a0aSOwen Pan 3345469c8a0aSOwen Pan Tokens = annotate("struct Foo<int> {};"); 3346469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 9u) << Tokens; 3347469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[5], BK_Block); 3348469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_Block); 3349469c8a0aSOwen Pan 33503db1f311SOwen Pan Tokens = annotate("struct Foo<int>::Bar {};"); 33513db1f311SOwen Pan ASSERT_EQ(Tokens.size(), 11u) << Tokens; 33523db1f311SOwen Pan EXPECT_BRACE_KIND(Tokens[7], BK_Block); 33533db1f311SOwen Pan EXPECT_BRACE_KIND(Tokens[8], BK_Block); 33543db1f311SOwen Pan 335588d351e2SOwen Pan Tokens = annotate("struct Foo<int> : Base {};"); 335688d351e2SOwen Pan ASSERT_EQ(Tokens.size(), 11u) << Tokens; 335788d351e2SOwen Pan EXPECT_BRACE_KIND(Tokens[7], BK_Block); 335888d351e2SOwen Pan EXPECT_BRACE_KIND(Tokens[8], BK_Block); 335988d351e2SOwen Pan 3360469c8a0aSOwen Pan Tokens = annotate("struct Foo final {};"); 3361469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3362469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[3], BK_Block); 3363469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_Block); 3364469c8a0aSOwen Pan 3365469c8a0aSOwen Pan Tokens = annotate("struct [[foo]] [[bar]] Foo final : Base1, Base2 {};"); 3366469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 21u) << Tokens; 3367469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[17], BK_Block); 3368469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[18], BK_Block); 3369469c8a0aSOwen Pan 3370469c8a0aSOwen Pan Tokens = annotate("struct Foo x{};"); 3371469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3372469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[3], BK_BracedInit); 3373469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_BracedInit); 3374469c8a0aSOwen Pan 3375469c8a0aSOwen Pan Tokens = annotate("struct ::Foo x{};"); 3376469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 8u) << Tokens; 3377469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_BracedInit); 3378469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[5], BK_BracedInit); 3379469c8a0aSOwen Pan 3380469c8a0aSOwen Pan Tokens = annotate("struct NS::Foo x{};"); 3381469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 9u) << Tokens; 3382469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[5], BK_BracedInit); 3383469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_BracedInit); 3384469c8a0aSOwen Pan 3385469c8a0aSOwen Pan Tokens = annotate("struct Foo<int> x{};"); 3386469c8a0aSOwen Pan ASSERT_EQ(Tokens.size(), 10u) << Tokens; 3387469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[6], BK_BracedInit); 3388469c8a0aSOwen Pan EXPECT_BRACE_KIND(Tokens[7], BK_BracedInit); 33894b10ade1SOwen Pan 33904b10ade1SOwen Pan Tokens = annotate("#ifdef DEBUG_ENABLED\n" 33914b10ade1SOwen Pan "#else\n" 33924b10ade1SOwen Pan "#endif\n" 33934b10ade1SOwen Pan "class RenderingServer : Object {\n" 33944b10ade1SOwen Pan "#ifndef DISABLE_DEPRECATED\n" 33954b10ade1SOwen Pan " enum Features {\n" 33964b10ade1SOwen Pan " FEATURE_SHADERS,\n" 33974b10ade1SOwen Pan " FEATURE_MULTITHREADED,\n" 33984b10ade1SOwen Pan " };\n" 33994b10ade1SOwen Pan "#endif\n" 34004b10ade1SOwen Pan "};"); 34014b10ade1SOwen Pan ASSERT_EQ(Tokens.size(), 29u) << Tokens; 34024b10ade1SOwen Pan EXPECT_BRACE_KIND(Tokens[11], BK_Block); 34034b10ade1SOwen Pan EXPECT_BRACE_KIND(Tokens[17], BK_Block); 34044b10ade1SOwen Pan EXPECT_BRACE_KIND(Tokens[22], BK_Block); 34054b10ade1SOwen Pan EXPECT_BRACE_KIND(Tokens[26], BK_Block); 3406ee235996SOwen Pan 3407ee235996SOwen Pan Tokens = annotate("{\n" 3408ee235996SOwen Pan "#define M(x) \\\n" 3409ee235996SOwen Pan " return {#x};\n" 3410ee235996SOwen Pan "}"); 3411ee235996SOwen Pan ASSERT_EQ(Tokens.size(), 15u) << Tokens; 3412ee235996SOwen Pan EXPECT_TOKEN(Tokens[0], tok::l_brace, TT_BlockLBrace); 3413ee235996SOwen Pan EXPECT_BRACE_KIND(Tokens[0], BK_Block); 3414ee235996SOwen Pan EXPECT_BRACE_KIND(Tokens[8], BK_BracedInit); 3415ee235996SOwen Pan EXPECT_BRACE_KIND(Tokens[11], BK_BracedInit); 3416ee235996SOwen Pan EXPECT_BRACE_KIND(Tokens[13], BK_Block); 341777d63cfdSKrasimir Georgiev 341854ca1c42SOwen Pan Tokens = annotate("{\n" 341954ca1c42SOwen Pan " {\n" 342054ca1c42SOwen Pan "#define GEN_ID(_x) char *_x{#_x}\n" 342154ca1c42SOwen Pan " GEN_ID(one);\n" 342254ca1c42SOwen Pan " }\n" 342354ca1c42SOwen Pan "}"); 342454ca1c42SOwen Pan ASSERT_EQ(Tokens.size(), 23u) << Tokens; 342554ca1c42SOwen Pan EXPECT_TOKEN(Tokens[0], tok::l_brace, TT_BlockLBrace); 342654ca1c42SOwen Pan EXPECT_BRACE_KIND(Tokens[0], BK_Block); 342754ca1c42SOwen Pan EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_BlockLBrace); 342854ca1c42SOwen Pan EXPECT_BRACE_KIND(Tokens[1], BK_Block); 342954ca1c42SOwen Pan EXPECT_BRACE_KIND(Tokens[11], BK_BracedInit); 343054ca1c42SOwen Pan EXPECT_BRACE_KIND(Tokens[14], BK_BracedInit); 343154ca1c42SOwen Pan EXPECT_BRACE_KIND(Tokens[20], BK_Block); 343254ca1c42SOwen Pan EXPECT_BRACE_KIND(Tokens[21], BK_Block); 343354ca1c42SOwen Pan 3434a7bca186SOwen Pan Tokens = annotate("{\n" 3435a7bca186SOwen Pan "#define FOO \\\n" 3436a7bca186SOwen Pan " { \\\n" 3437a7bca186SOwen Pan " case bar: { \\\n" 3438a7bca186SOwen Pan " break; \\\n" 3439a7bca186SOwen Pan " } \\\n" 3440a7bca186SOwen Pan " }\n" 3441a7bca186SOwen Pan "}"); 3442a7bca186SOwen Pan ASSERT_EQ(Tokens.size(), 15u) << Tokens; 3443a7bca186SOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_BlockLBrace); 3444a7bca186SOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_Block); 3445a7bca186SOwen Pan EXPECT_TOKEN(Tokens[7], tok::colon, TT_CaseLabelColon); 3446a7bca186SOwen Pan EXPECT_BRACE_KIND(Tokens[8], BK_Block); 3447a7bca186SOwen Pan EXPECT_BRACE_KIND(Tokens[11], BK_Block); 3448a7bca186SOwen Pan EXPECT_BRACE_KIND(Tokens[12], BK_Block); 3449a7bca186SOwen Pan 345077d63cfdSKrasimir Georgiev Tokens = annotate("a = class extends goog.a {};", 345177d63cfdSKrasimir Georgiev getGoogleStyle(FormatStyle::LK_JavaScript)); 345277d63cfdSKrasimir Georgiev ASSERT_EQ(Tokens.size(), 11u) << Tokens; 345377d63cfdSKrasimir Georgiev EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_ClassLBrace); 345477d63cfdSKrasimir Georgiev EXPECT_BRACE_KIND(Tokens[7], BK_Block); 34557579787eSOwen Pan EXPECT_TOKEN(Tokens[8], tok::r_brace, TT_ClassRBrace); 34567579787eSOwen Pan EXPECT_BRACE_KIND(Tokens[8], BK_Block); 34577579787eSOwen Pan 345804d71ea1Skadir çetinkaya Tokens = annotate("a = class Foo extends goog.a {};", 345904d71ea1Skadir çetinkaya getGoogleStyle(FormatStyle::LK_JavaScript)); 346004d71ea1Skadir çetinkaya ASSERT_EQ(Tokens.size(), 12u) << Tokens; 346104d71ea1Skadir çetinkaya EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_ClassLBrace); 346204d71ea1Skadir çetinkaya EXPECT_BRACE_KIND(Tokens[8], BK_Block); 346304d71ea1Skadir çetinkaya EXPECT_TOKEN(Tokens[9], tok::r_brace, TT_ClassRBrace); 346404d71ea1Skadir çetinkaya EXPECT_BRACE_KIND(Tokens[9], BK_Block); 346504d71ea1Skadir çetinkaya 34667579787eSOwen Pan Tokens = annotate("#define FOO(X) \\\n" 34677579787eSOwen Pan " struct X##_tag_ {};"); 34687579787eSOwen Pan ASSERT_EQ(Tokens.size(), 14u) << Tokens; 34697579787eSOwen Pan EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_StructLBrace); 34707579787eSOwen Pan EXPECT_BRACE_KIND(Tokens[10], BK_Block); 34717579787eSOwen Pan EXPECT_TOKEN(Tokens[11], tok::r_brace, TT_StructRBrace); 34727579787eSOwen Pan EXPECT_BRACE_KIND(Tokens[11], BK_Block); 3473616a8ce6SOwen Pan 3474616a8ce6SOwen Pan Tokens = annotate("#define MACRO \\\n" 3475616a8ce6SOwen Pan " struct hash<type> { \\\n" 3476616a8ce6SOwen Pan " void f() { return; } \\\n" 3477616a8ce6SOwen Pan " };"); 3478616a8ce6SOwen Pan ASSERT_EQ(Tokens.size(), 20u) << Tokens; 3479616a8ce6SOwen Pan EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_StructLBrace); 3480616a8ce6SOwen Pan EXPECT_BRACE_KIND(Tokens[8], BK_Block); 3481616a8ce6SOwen Pan EXPECT_TOKEN(Tokens[10], tok::identifier, TT_FunctionDeclarationName); 3482616a8ce6SOwen Pan EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_FunctionDeclarationLParen); 3483616a8ce6SOwen Pan EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_FunctionLBrace); 3484616a8ce6SOwen Pan EXPECT_BRACE_KIND(Tokens[13], BK_Block); 3485616a8ce6SOwen Pan EXPECT_BRACE_KIND(Tokens[16], BK_Block); 3486616a8ce6SOwen Pan EXPECT_TOKEN(Tokens[17], tok::r_brace, TT_StructRBrace); 3487616a8ce6SOwen Pan EXPECT_BRACE_KIND(Tokens[17], BK_Block); 3488616a8ce6SOwen Pan 3489616a8ce6SOwen Pan Tokens = annotate("#define MEMBER(NAME) NAME{\"\"}"); 3490616a8ce6SOwen Pan ASSERT_EQ(Tokens.size(), 11u) << Tokens; 3491616a8ce6SOwen Pan EXPECT_BRACE_KIND(Tokens[7], BK_BracedInit); 3492616a8ce6SOwen Pan EXPECT_BRACE_KIND(Tokens[9], BK_BracedInit); 3493edad025dSOwen Pan } 3494edad025dSOwen Pan 34957e7f1184SXDeme TEST_F(TokenAnnotatorTest, UnderstandsElaboratedTypeSpecifier) { 34967e7f1184SXDeme auto Tokens = annotate("auto foo() -> enum En {}"); 34977e7f1184SXDeme ASSERT_EQ(Tokens.size(), 10u) << Tokens; 34987e7f1184SXDeme EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_FunctionLBrace); 34997e7f1184SXDeme } 35007e7f1184SXDeme 350151f16814SOwen Pan TEST_F(TokenAnnotatorTest, BlockLBrace) { 350251f16814SOwen Pan auto Tokens = annotate("{\n" 350351f16814SOwen Pan " {\n" 350451f16814SOwen Pan " foo();\n" 350551f16814SOwen Pan " }\n" 350651f16814SOwen Pan "}"); 350751f16814SOwen Pan ASSERT_EQ(Tokens.size(), 9u) << Tokens; 350851f16814SOwen Pan EXPECT_TOKEN(Tokens[0], tok::l_brace, TT_BlockLBrace); 350951f16814SOwen Pan EXPECT_BRACE_KIND(Tokens[0], BK_Block); 351051f16814SOwen Pan EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_BlockLBrace); 351151f16814SOwen Pan EXPECT_BRACE_KIND(Tokens[1], BK_Block); 351251f16814SOwen Pan 351351f16814SOwen Pan Tokens = annotate("void bar() {\n" 351451f16814SOwen Pan " {\n" 351551f16814SOwen Pan " foo();\n" 351651f16814SOwen Pan " }\n" 351751f16814SOwen Pan "}"); 351851f16814SOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 351951f16814SOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace); 352051f16814SOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_Block); 352151f16814SOwen Pan EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_BlockLBrace); 352251f16814SOwen Pan EXPECT_BRACE_KIND(Tokens[5], BK_Block); 3523e0f2368cSOwen Pan 3524e0f2368cSOwen Pan Tokens = annotate("[foo bar:{{0, 1}} baz:baz];", 3525e0f2368cSOwen Pan getLLVMStyle(FormatStyle::LK_ObjC)); 3526e0f2368cSOwen Pan ASSERT_EQ(Tokens.size(), 17u) << Tokens; 3527e0f2368cSOwen Pan EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_Unknown); // Not TT_BlockLBrace. 3528e0f2368cSOwen Pan EXPECT_BRACE_KIND(Tokens[4], BK_Unknown); // Not BK_Block. 3529e0f2368cSOwen Pan EXPECT_BRACE_KIND(Tokens[5], BK_BracedInit); 3530e0f2368cSOwen Pan EXPECT_BRACE_KIND(Tokens[9], BK_Unknown); // Not BK_Block. 3531e0f2368cSOwen Pan EXPECT_BRACE_KIND(Tokens[10], BK_Unknown); // Not BK_Block. 353251f16814SOwen Pan } 353351f16814SOwen Pan 3534236b3e1aSOwen Pan TEST_F(TokenAnnotatorTest, SwitchExpression) { 3535236b3e1aSOwen Pan auto Style = getLLVMStyle(FormatStyle::LK_Java); 3536236b3e1aSOwen Pan auto Tokens = annotate("i = switch (day) {\n" 3537236b3e1aSOwen Pan " case THURSDAY, SATURDAY -> 8;\n" 3538236b3e1aSOwen Pan " case WEDNESDAY -> 9;\n" 3539236b3e1aSOwen Pan " default -> 1;\n" 3540236b3e1aSOwen Pan "};", 3541236b3e1aSOwen Pan Style); 3542236b3e1aSOwen Pan ASSERT_EQ(Tokens.size(), 26u) << Tokens; 3543236b3e1aSOwen Pan EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_SwitchExpressionLBrace); 3544236b3e1aSOwen Pan EXPECT_TOKEN(Tokens[7], tok::kw_case, TT_SwitchExpressionLabel); 3545236b3e1aSOwen Pan EXPECT_TOKEN(Tokens[11], tok::arrow, TT_CaseLabelArrow); 3546236b3e1aSOwen Pan EXPECT_TOKEN(Tokens[14], tok::kw_case, TT_SwitchExpressionLabel); 3547236b3e1aSOwen Pan EXPECT_TOKEN(Tokens[16], tok::arrow, TT_CaseLabelArrow); 3548236b3e1aSOwen Pan EXPECT_TOKEN(Tokens[19], tok::kw_default, TT_SwitchExpressionLabel); 3549236b3e1aSOwen Pan EXPECT_TOKEN(Tokens[20], tok::arrow, TT_CaseLabelArrow); 3550236b3e1aSOwen Pan } 3551236b3e1aSOwen Pan 3552a6d97decSOwen Pan TEST_F(TokenAnnotatorTest, CppAltOperatorKeywords) { 3553a6d97decSOwen Pan auto Tokens = annotate("a = b and c;"); 355494698369SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3555a6d97decSOwen Pan EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_BinaryOperator); 3556a6d97decSOwen Pan 3557a6d97decSOwen Pan Tokens = annotate("a = b and_eq c;"); 355894698369SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3559a6d97decSOwen Pan EXPECT_TOKEN(Tokens[3], tok::ampequal, TT_BinaryOperator); 3560a6d97decSOwen Pan 3561a6d97decSOwen Pan Tokens = annotate("a = b bitand c;"); 356294698369SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3563a6d97decSOwen Pan EXPECT_TOKEN(Tokens[3], tok::amp, TT_BinaryOperator); 3564a6d97decSOwen Pan 3565a6d97decSOwen Pan Tokens = annotate("a = b bitor c;"); 356694698369SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3567a6d97decSOwen Pan EXPECT_TOKEN(Tokens[3], tok::pipe, TT_BinaryOperator); 3568a6d97decSOwen Pan 3569a6d97decSOwen Pan Tokens = annotate("a = b compl c;"); 357094698369SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3571a6d97decSOwen Pan EXPECT_TOKEN(Tokens[3], tok::tilde, TT_UnaryOperator); 3572a6d97decSOwen Pan 3573a6d97decSOwen Pan Tokens = annotate("a = b not c;"); 357494698369SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3575a6d97decSOwen Pan EXPECT_TOKEN(Tokens[3], tok::exclaim, TT_UnaryOperator); 3576a6d97decSOwen Pan 3577a6d97decSOwen Pan Tokens = annotate("a = b not_eq c;"); 357894698369SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3579a6d97decSOwen Pan EXPECT_TOKEN(Tokens[3], tok::exclaimequal, TT_BinaryOperator); 3580a6d97decSOwen Pan 3581a6d97decSOwen Pan Tokens = annotate("a = b or c;"); 358294698369SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3583a6d97decSOwen Pan EXPECT_TOKEN(Tokens[3], tok::pipepipe, TT_BinaryOperator); 3584a6d97decSOwen Pan 3585a6d97decSOwen Pan Tokens = annotate("a = b or_eq c;"); 358694698369SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3587a6d97decSOwen Pan EXPECT_TOKEN(Tokens[3], tok::pipeequal, TT_BinaryOperator); 3588a6d97decSOwen Pan 3589a6d97decSOwen Pan Tokens = annotate("a = b xor c;"); 359094698369SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3591a6d97decSOwen Pan EXPECT_TOKEN(Tokens[3], tok::caret, TT_BinaryOperator); 3592a6d97decSOwen Pan 3593a6d97decSOwen Pan Tokens = annotate("a = b xor_eq c;"); 359494698369SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 3595a6d97decSOwen Pan EXPECT_TOKEN(Tokens[3], tok::caretequal, TT_BinaryOperator); 3596a6d97decSOwen Pan 3597a6d97decSOwen Pan Tokens = annotate("xor = foo;"); 359894698369SOwen Pan ASSERT_EQ(Tokens.size(), 5u) << Tokens; 3599a6d97decSOwen Pan EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown); 3600a6d97decSOwen Pan 3601a6d97decSOwen Pan Tokens = annotate("int xor = foo;"); 360294698369SOwen Pan ASSERT_EQ(Tokens.size(), 6u) << Tokens; 3603a6d97decSOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_StartOfName); 3604a6d97decSOwen Pan } 3605a6d97decSOwen Pan 360661571e90SOwen Pan TEST_F(TokenAnnotatorTest, FunctionTryBlock) { 360761571e90SOwen Pan auto Tokens = 360861571e90SOwen Pan annotate("Foo::Foo(int x, int y) try\n" 360961571e90SOwen Pan " : foo{[] -> std::string { return {}; }(), x}, bar{y} {\n" 361061571e90SOwen Pan "} catch (...) {\n" 361161571e90SOwen Pan "}"); 361294698369SOwen Pan ASSERT_EQ(Tokens.size(), 45u) << Tokens; 361361571e90SOwen Pan EXPECT_TOKEN(Tokens[2], tok::identifier, TT_CtorDtorDeclName); 3614b2ac7f52SOwen Pan EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_FunctionDeclarationLParen); 361561571e90SOwen Pan EXPECT_TOKEN(Tokens[11], tok::colon, TT_CtorInitializerColon); 361661571e90SOwen Pan EXPECT_TOKEN(Tokens[14], tok::l_square, TT_LambdaLSquare); 3617438ad9f2SOwen Pan EXPECT_TOKEN(Tokens[16], tok::arrow, TT_LambdaArrow); 361861571e90SOwen Pan EXPECT_TOKEN(Tokens[20], tok::l_brace, TT_LambdaLBrace); 361961571e90SOwen Pan EXPECT_TOKEN(Tokens[31], tok::comma, TT_CtorInitializerComma); 362061571e90SOwen Pan EXPECT_TOKEN(Tokens[36], tok::l_brace, TT_FunctionLBrace); 362161571e90SOwen Pan } 362261571e90SOwen Pan 3623fa00e8bbSOwen Pan TEST_F(TokenAnnotatorTest, TypenameMacro) { 3624fa00e8bbSOwen Pan auto Style = getLLVMStyle(); 3625fa00e8bbSOwen Pan Style.TypenameMacros.push_back("STRUCT"); 3626fa00e8bbSOwen Pan 3627fa00e8bbSOwen Pan auto Tokens = annotate("STRUCT(T, B) { int i; };", Style); 362894698369SOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 3629fa00e8bbSOwen Pan EXPECT_TOKEN(Tokens[0], tok::identifier, TT_TypenameMacro); 3630fa00e8bbSOwen Pan EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_TypeDeclarationParen); 3631fa00e8bbSOwen Pan EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_TypeDeclarationParen); 3632fa00e8bbSOwen Pan EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_Unknown); 3633fa00e8bbSOwen Pan } 3634fa00e8bbSOwen Pan 36353496245eSOwen Pan TEST_F(TokenAnnotatorTest, GNULanguageStandard) { 36363496245eSOwen Pan auto Style = getGNUStyle(); 36373496245eSOwen Pan EXPECT_EQ(Style.Standard, FormatStyle::LS_Latest); 36383496245eSOwen Pan 36393496245eSOwen Pan auto Tokens = annotate("return 1 <=> 2;", Style); 364094698369SOwen Pan ASSERT_EQ(Tokens.size(), 6u) << Tokens; 36413496245eSOwen Pan EXPECT_TOKEN(Tokens[2], tok::spaceship, TT_BinaryOperator); 36423496245eSOwen Pan } 36433496245eSOwen Pan 3644438ad9f2SOwen Pan TEST_F(TokenAnnotatorTest, SplitPenalty) { 3645438ad9f2SOwen Pan auto Style = getLLVMStyle(); 3646438ad9f2SOwen Pan Style.ColumnLimit = 20; 3647438ad9f2SOwen Pan 3648438ad9f2SOwen Pan auto Tokens = annotate("class foo {\n" 3649438ad9f2SOwen Pan " auto bar()\n" 3650438ad9f2SOwen Pan " -> bool;\n" 3651438ad9f2SOwen Pan "};", 3652438ad9f2SOwen Pan Style); 3653438ad9f2SOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 3654438ad9f2SOwen Pan EXPECT_TOKEN(Tokens[7], tok::arrow, TT_TrailingReturnArrow); 3655438ad9f2SOwen Pan EXPECT_SPLIT_PENALTY(Tokens[7], 23u); 3656438ad9f2SOwen Pan } 3657438ad9f2SOwen Pan 3658688bc958SOwen Pan TEST_F(TokenAnnotatorTest, TemplateName) { 3659688bc958SOwen Pan constexpr StringRef Code{"return Foo < A || B > (C ^ D);"}; 3660688bc958SOwen Pan 3661688bc958SOwen Pan auto Tokens = annotate(Code); 3662688bc958SOwen Pan ASSERT_EQ(Tokens.size(), 14u) << Tokens; 3663688bc958SOwen Pan EXPECT_TOKEN(Tokens[2], tok::less, TT_BinaryOperator); 3664688bc958SOwen Pan EXPECT_TOKEN(Tokens[6], tok::greater, TT_BinaryOperator); 3665688bc958SOwen Pan 3666688bc958SOwen Pan auto Style = getLLVMStyle(); 3667688bc958SOwen Pan Style.TemplateNames.push_back("Foo"); 3668688bc958SOwen Pan 3669688bc958SOwen Pan Tokens = annotate(Code, Style); 3670688bc958SOwen Pan EXPECT_TOKEN(Tokens[1], tok::identifier, TT_TemplateName); 3671688bc958SOwen Pan EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 3672688bc958SOwen Pan EXPECT_TOKEN(Tokens[6], tok::greater, TT_TemplateCloser); 3673688bc958SOwen Pan } 3674688bc958SOwen Pan 367514e1fef7SOwen Pan TEST_F(TokenAnnotatorTest, TemplateInstantiation) { 367614e1fef7SOwen Pan auto Tokens = annotate("return FixedInt<N | M>();"); 367714e1fef7SOwen Pan ASSERT_EQ(Tokens.size(), 11u) << Tokens; 367814e1fef7SOwen Pan EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 367914e1fef7SOwen Pan EXPECT_TOKEN(Tokens[6], tok::greater, TT_TemplateCloser); 3680e5b05a51SOwen Pan 3681*1e89355dSOwen Pan Tokens = annotate("return FixedInt<N | M>(foo);"); 3682*1e89355dSOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 3683*1e89355dSOwen Pan EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener); 3684*1e89355dSOwen Pan EXPECT_TOKEN(Tokens[6], tok::greater, TT_TemplateCloser); 3685*1e89355dSOwen Pan 3686e5b05a51SOwen Pan Tokens = annotate("return std::conditional_t<T::value == U::value, T, U>{};"); 3687e5b05a51SOwen Pan ASSERT_EQ(Tokens.size(), 21u) << Tokens; 3688e5b05a51SOwen Pan EXPECT_TOKEN(Tokens[4], tok::less, TT_TemplateOpener); 3689e5b05a51SOwen Pan EXPECT_TOKEN(Tokens[16], tok::greater, TT_TemplateCloser); 369067f576f3SOwen Pan 369167f576f3SOwen Pan Tokens = 369267f576f3SOwen Pan annotate("auto x{std::conditional_t<T::value == U::value, T, U>{}};"); 369367f576f3SOwen Pan ASSERT_EQ(Tokens.size(), 24u) << Tokens; 369467f576f3SOwen Pan EXPECT_TOKEN(Tokens[6], tok::less, TT_TemplateOpener); 369567f576f3SOwen Pan EXPECT_TOKEN(Tokens[18], tok::greater, TT_TemplateCloser); 369614e1fef7SOwen Pan } 369714e1fef7SOwen Pan 36981a0d0ae2SOwen Pan TEST_F(TokenAnnotatorTest, VariableTemplate) { 36991a0d0ae2SOwen Pan auto Style = getLLVMStyle(); 37001a0d0ae2SOwen Pan Style.VariableTemplates.push_back("a"); 37011a0d0ae2SOwen Pan 37021a0d0ae2SOwen Pan auto Tokens = annotate("auto t3 = (a<int>) + b;", Style); 37031a0d0ae2SOwen Pan ASSERT_EQ(Tokens.size(), 13u) << Tokens; 37041a0d0ae2SOwen Pan EXPECT_TOKEN(Tokens[4], tok::identifier, TT_VariableTemplate); 37051a0d0ae2SOwen Pan EXPECT_TOKEN(Tokens[5], tok::less, TT_TemplateOpener); 37061a0d0ae2SOwen Pan EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser); 37071a0d0ae2SOwen Pan EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown); // Not TT_CastRParen 37081a0d0ae2SOwen Pan EXPECT_TOKEN(Tokens[9], tok::plus, TT_BinaryOperator); 37091a0d0ae2SOwen Pan } 37101a0d0ae2SOwen Pan 37116ca816f8SOwen Pan TEST_F(TokenAnnotatorTest, SwitchInMacroArgument) { 37126ca816f8SOwen Pan auto Tokens = annotate("FOOBAR(switch);\n" 37136ca816f8SOwen Pan "void f() {}"); 37146ca816f8SOwen Pan ASSERT_EQ(Tokens.size(), 12u) << Tokens; 37156ca816f8SOwen Pan EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_FunctionLBrace); 37166ca816f8SOwen Pan } 37176ca816f8SOwen Pan 371844b83e81SOwen Pan TEST_F(TokenAnnotatorTest, AfterPPDirective) { 371944b83e81SOwen Pan auto Tokens = annotate("#error -- My error message"); 372044b83e81SOwen Pan 372144b83e81SOwen Pan ASSERT_EQ(Tokens.size(), 7u) << Tokens; 372244b83e81SOwen Pan EXPECT_TOKEN(Tokens[2], tok::minusminus, TT_AfterPPDirective); 372344b83e81SOwen Pan } 372444b83e81SOwen Pan 372585032534SAlex Richardson } // namespace 372685032534SAlex Richardson } // namespace format 372785032534SAlex Richardson } // namespace clang 3728