5767 lines
116 KiB
C++
5767 lines
116 KiB
C++
//===- BuildTreeTest.cpp --------------------------------------------------===//
|
||
//
|
||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
// See https://llvm.org/LICENSE.txt for license information.
|
||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
//
|
||
//===----------------------------------------------------------------------===//
|
||
//
|
||
// This file tests the syntax tree generation from the ClangAST.
|
||
//
|
||
//===----------------------------------------------------------------------===//
|
||
|
||
#include "TreeTestBase.h"
|
||
|
||
using namespace clang;
|
||
using namespace clang::syntax;
|
||
|
||
namespace {
|
||
|
||
class BuildSyntaxTreeTest : public SyntaxTreeTest {
|
||
protected:
|
||
::testing::AssertionResult treeDumpEqual(StringRef Code, StringRef Tree) {
|
||
SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
|
||
|
||
auto *Root = buildTree(Code, GetParam());
|
||
if (Diags->getClient()->getNumErrors() != 0) {
|
||
return ::testing::AssertionFailure()
|
||
<< "Source file has syntax errors, they were printed to the test "
|
||
"log";
|
||
}
|
||
auto Actual = StringRef(Root->dump(Arena->getSourceManager())).trim().str();
|
||
// EXPECT_EQ shows the diff between the two strings if they are different.
|
||
EXPECT_EQ(Tree.trim().str(), Actual);
|
||
if (Actual != Tree.trim().str()) {
|
||
return ::testing::AssertionFailure();
|
||
}
|
||
return ::testing::AssertionSuccess();
|
||
}
|
||
|
||
::testing::AssertionResult
|
||
treeDumpEqualOnAnnotations(StringRef CodeWithAnnotations,
|
||
ArrayRef<StringRef> TreeDumps) {
|
||
SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
|
||
|
||
auto AnnotatedCode = llvm::Annotations(CodeWithAnnotations);
|
||
auto *Root = buildTree(AnnotatedCode.code(), GetParam());
|
||
|
||
if (Diags->getClient()->getNumErrors() != 0) {
|
||
return ::testing::AssertionFailure()
|
||
<< "Source file has syntax errors, they were printed to the test "
|
||
"log";
|
||
}
|
||
|
||
auto AnnotatedRanges = AnnotatedCode.ranges();
|
||
if (AnnotatedRanges.size() != TreeDumps.size()) {
|
||
return ::testing::AssertionFailure()
|
||
<< "The number of annotated ranges in the source code is "
|
||
"different "
|
||
"to the number of their corresponding tree dumps.";
|
||
}
|
||
bool Failed = false;
|
||
for (unsigned i = 0; i < AnnotatedRanges.size(); i++) {
|
||
auto *AnnotatedNode = nodeByRange(AnnotatedRanges[i], Root);
|
||
assert(AnnotatedNode);
|
||
auto AnnotatedNodeDump =
|
||
StringRef(AnnotatedNode->dump(Arena->getSourceManager()))
|
||
.trim()
|
||
.str();
|
||
// EXPECT_EQ shows the diff between the two strings if they are different.
|
||
EXPECT_EQ(TreeDumps[i].trim().str(), AnnotatedNodeDump)
|
||
<< "Dumps diverged for the code:\n"
|
||
<< AnnotatedCode.code().slice(AnnotatedRanges[i].Begin,
|
||
AnnotatedRanges[i].End);
|
||
if (AnnotatedNodeDump != TreeDumps[i].trim().str())
|
||
Failed = true;
|
||
}
|
||
return Failed ? ::testing::AssertionFailure()
|
||
: ::testing::AssertionSuccess();
|
||
}
|
||
};
|
||
|
||
INSTANTIATE_TEST_CASE_P(SyntaxTreeTests, BuildSyntaxTreeTest,
|
||
testing::ValuesIn(allTestClangConfigs()), );
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Simple) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int main() {}
|
||
void foo() {}
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'main'
|
||
| | `-ParametersAndQualifiers
|
||
| | |-'(' OpenParen
|
||
| | `-')' CloseParen
|
||
| `-CompoundStatement
|
||
| |-'{' OpenParen
|
||
| `-'}' CloseParen
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'foo'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-CompoundStatement
|
||
|-'{' OpenParen
|
||
`-'}' CloseParen
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, SimpleVariable) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int a;
|
||
int b = 42;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'a'
|
||
| `-';'
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'b'
|
||
| |-'='
|
||
| `-IntegerLiteralExpression
|
||
| `-'42' LiteralToken
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, SimpleFunction) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
void foo(int a, int b) {}
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'foo'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | |-'int'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | `-'a'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'int'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'b'
|
||
| `-')' CloseParen
|
||
`-CompoundStatement
|
||
|-'{' OpenParen
|
||
`-'}' CloseParen
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Simple_BackslashInsideToken) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
in\
|
||
t a;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'in\
|
||
t'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| `-'a'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, If) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[if (1) {}]]
|
||
[[if (1) {} else if (0) {}]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
IfStatement Statement
|
||
|-'if' IntroducerKeyword
|
||
|-'('
|
||
|-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
|-')'
|
||
`-CompoundStatement ThenStatement
|
||
|-'{' OpenParen
|
||
`-'}' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
IfStatement Statement
|
||
|-'if' IntroducerKeyword
|
||
|-'('
|
||
|-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
|-')'
|
||
|-CompoundStatement ThenStatement
|
||
| |-'{' OpenParen
|
||
| `-'}' CloseParen
|
||
|-'else' ElseKeyword
|
||
`-IfStatement ElseStatement
|
||
|-'if' IntroducerKeyword
|
||
|-'('
|
||
|-IntegerLiteralExpression
|
||
| `-'0' LiteralToken
|
||
|-')'
|
||
`-CompoundStatement ThenStatement
|
||
|-'{' OpenParen
|
||
`-'}' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, For) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[for (;;) {}]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ForStatement Statement
|
||
|-'for' IntroducerKeyword
|
||
|-'('
|
||
|-';'
|
||
|-';'
|
||
|-')'
|
||
`-CompoundStatement BodyStatement
|
||
|-'{' OpenParen
|
||
`-'}' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, RangeBasedFor) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
int a[3];
|
||
[[for (int x : a)
|
||
;]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
RangeBasedForStatement Statement
|
||
|-'for' IntroducerKeyword
|
||
|-'('
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'x'
|
||
| `-':'
|
||
|-IdExpression
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'a'
|
||
|-')'
|
||
`-EmptyStatement BodyStatement
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, DeclarationStatement) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[int a = 10;]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
DeclarationStatement Statement
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| `-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'a'
|
||
| |-'='
|
||
| `-IntegerLiteralExpression
|
||
| `-'10' LiteralToken
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Switch) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[switch (1) {
|
||
case 0:
|
||
default:;
|
||
}]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
SwitchStatement Statement
|
||
|-'switch' IntroducerKeyword
|
||
|-'('
|
||
|-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
|-')'
|
||
`-CompoundStatement BodyStatement
|
||
|-'{' OpenParen
|
||
|-CaseStatement Statement
|
||
| |-'case' IntroducerKeyword
|
||
| |-IntegerLiteralExpression CaseValue
|
||
| | `-'0' LiteralToken
|
||
| |-':'
|
||
| `-DefaultStatement BodyStatement
|
||
| |-'default' IntroducerKeyword
|
||
| |-':'
|
||
| `-EmptyStatement BodyStatement
|
||
| `-';'
|
||
`-'}' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, While) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[while (1) { continue; break; }]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
WhileStatement Statement
|
||
|-'while' IntroducerKeyword
|
||
|-'('
|
||
|-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
|-')'
|
||
`-CompoundStatement BodyStatement
|
||
|-'{' OpenParen
|
||
|-ContinueStatement Statement
|
||
| |-'continue' IntroducerKeyword
|
||
| `-';'
|
||
|-BreakStatement Statement
|
||
| |-'break' IntroducerKeyword
|
||
| `-';'
|
||
`-'}' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UnhandledStatement) {
|
||
// Unhandled statements should end up as 'unknown statement'.
|
||
// This example uses a 'label statement', which does not yet have a syntax
|
||
// counterpart.
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
int test() {
|
||
[[foo: return 100;]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
UnknownStatement Statement
|
||
|-'foo'
|
||
|-':'
|
||
`-ReturnStatement
|
||
|-'return' IntroducerKeyword
|
||
|-IntegerLiteralExpression ReturnValue
|
||
| `-'100' LiteralToken
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Expressions) {
|
||
// expressions should be wrapped in 'ExpressionStatement' when they appear
|
||
// in a statement position.
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
void test() {
|
||
test();
|
||
if (1) test(); else test();
|
||
}
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'test'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-CompoundStatement
|
||
|-'{' OpenParen
|
||
|-ExpressionStatement Statement
|
||
| |-CallExpression Expression
|
||
| | |-IdExpression Callee
|
||
| | | `-UnqualifiedId UnqualifiedId
|
||
| | | `-'test'
|
||
| | |-'(' OpenParen
|
||
| | `-')' CloseParen
|
||
| `-';'
|
||
|-IfStatement Statement
|
||
| |-'if' IntroducerKeyword
|
||
| |-'('
|
||
| |-IntegerLiteralExpression
|
||
| | `-'1' LiteralToken
|
||
| |-')'
|
||
| |-ExpressionStatement ThenStatement
|
||
| | |-CallExpression Expression
|
||
| | | |-IdExpression Callee
|
||
| | | | `-UnqualifiedId UnqualifiedId
|
||
| | | | `-'test'
|
||
| | | |-'(' OpenParen
|
||
| | | `-')' CloseParen
|
||
| | `-';'
|
||
| |-'else' ElseKeyword
|
||
| `-ExpressionStatement ElseStatement
|
||
| |-CallExpression Expression
|
||
| | |-IdExpression Callee
|
||
| | | `-UnqualifiedId UnqualifiedId
|
||
| | | `-'test'
|
||
| | |-'(' OpenParen
|
||
| | `-')' CloseParen
|
||
| `-';'
|
||
`-'}' CloseParen
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UnqualifiedId_Identifier) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test(int a) {
|
||
[[a]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
IdExpression Expression
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UnqualifiedId_OperatorFunctionId) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
friend X operator+(const X&, const X&);
|
||
};
|
||
void test(X x) {
|
||
[[operator+(x, x)]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'operator'
|
||
| `-'+'
|
||
|-'(' OpenParen
|
||
|-CallArguments Arguments
|
||
| |-IdExpression ListElement
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'x'
|
||
| |-',' ListDelimiter
|
||
| `-IdExpression ListElement
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'x'
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UnqualifiedId_ConversionFunctionId) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
operator int();
|
||
};
|
||
void test(X x) {
|
||
[[x.operator int()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-IdExpression Object
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'x'
|
||
| |-'.' AccessToken
|
||
| `-IdExpression Member
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'operator'
|
||
| `-'int'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UnqualifiedId_LiteralOperatorId) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
unsigned operator "" _w(char);
|
||
void test() {
|
||
[[operator "" _w('1')]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'operator'
|
||
| |-'""'
|
||
| `-'_w'
|
||
|-'(' OpenParen
|
||
|-CallArguments Arguments
|
||
| `-CharacterLiteralExpression ListElement
|
||
| `-''1'' LiteralToken
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UnqualifiedId_Destructor) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X { };
|
||
void test(X x) {
|
||
[[x.~X()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-IdExpression Object
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'x'
|
||
| |-'.' AccessToken
|
||
| `-IdExpression Member
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'~'
|
||
| `-'X'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UnqualifiedId_DecltypeDestructor) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X { };
|
||
void test(X x) {
|
||
// FIXME: Make `decltype(x)` a child of `MemberExpression`. It is currently
|
||
// not because `Expr::getSourceRange()` returns the range of `x.~` for the
|
||
// `MemberExpr` instead of the expected `x.~decltype(x)`, this is a bug in
|
||
// clang.
|
||
[[x.~decltype(x)()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-IdExpression Object
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'x'
|
||
| |-'.' AccessToken
|
||
| `-IdExpression Member
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'~'
|
||
|-'decltype'
|
||
|-'('
|
||
|-'x'
|
||
|-')'
|
||
|-'('
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UnqualifiedId_TemplateId) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template<typename T>
|
||
T f();
|
||
void test() {
|
||
[[f<int>()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'f'
|
||
| |-'<'
|
||
| |-'int'
|
||
| `-'>'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, QualifiedId_NamespaceSpecifier) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
namespace n {
|
||
struct S { };
|
||
}
|
||
void test() {
|
||
[[::n::S s1]];
|
||
[[n::S s2]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-NestedNameSpecifier
|
||
| |-'::' ListDelimiter
|
||
| |-IdentifierNameSpecifier ListElement
|
||
| | `-'n'
|
||
| `-'::' ListDelimiter
|
||
|-'S'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
`-'s1'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-NestedNameSpecifier
|
||
| |-IdentifierNameSpecifier ListElement
|
||
| | `-'n'
|
||
| `-'::' ListDelimiter
|
||
|-'S'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
`-'s2'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, QualifiedId_TemplateSpecifier) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template<typename T>
|
||
struct ST {
|
||
struct S { };
|
||
};
|
||
void test() {
|
||
[[::template ST<int>::S s1]];
|
||
[[::ST<int>::S s2]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-NestedNameSpecifier
|
||
| |-'::' ListDelimiter
|
||
| |-SimpleTemplateNameSpecifier ListElement
|
||
| | |-'template'
|
||
| | |-'ST'
|
||
| | |-'<'
|
||
| | |-'int'
|
||
| | `-'>'
|
||
| `-'::' ListDelimiter
|
||
|-'S'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
`-'s1'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-NestedNameSpecifier
|
||
| |-'::' ListDelimiter
|
||
| |-SimpleTemplateNameSpecifier ListElement
|
||
| | |-'ST'
|
||
| | |-'<'
|
||
| | |-'int'
|
||
| | `-'>'
|
||
| `-'::' ListDelimiter
|
||
|-'S'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
`-'s2'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, QualifiedId_DecltypeSpecifier) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
static void f(){}
|
||
};
|
||
void test(S s) {
|
||
[[decltype(s)::f()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| |-NestedNameSpecifier Qualifier
|
||
| | |-DecltypeNameSpecifier ListElement
|
||
| | | |-'decltype'
|
||
| | | |-'('
|
||
| | | |-IdExpression
|
||
| | | | `-UnqualifiedId UnqualifiedId
|
||
| | | | `-'s'
|
||
| | | `-')'
|
||
| | `-'::' ListDelimiter
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'f'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, QualifiedId_OptionalTemplateKw) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
template<typename U>
|
||
static U f();
|
||
};
|
||
void test() {
|
||
[[S::f<int>()]];
|
||
[[S::template f<int>()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| |-NestedNameSpecifier Qualifier
|
||
| | |-IdentifierNameSpecifier ListElement
|
||
| | | `-'S'
|
||
| | `-'::' ListDelimiter
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'f'
|
||
| |-'<'
|
||
| |-'int'
|
||
| `-'>'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| |-NestedNameSpecifier Qualifier
|
||
| | |-IdentifierNameSpecifier ListElement
|
||
| | | `-'S'
|
||
| | `-'::' ListDelimiter
|
||
| |-'template' TemplateKeyword
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'f'
|
||
| |-'<'
|
||
| |-'int'
|
||
| `-'>'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, QualifiedId_Complex) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
namespace n {
|
||
template<typename T>
|
||
struct ST {
|
||
template<typename U>
|
||
static U f();
|
||
};
|
||
}
|
||
void test() {
|
||
[[::n::template ST<int>::template f<int>()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| |-NestedNameSpecifier Qualifier
|
||
| | |-'::' ListDelimiter
|
||
| | |-IdentifierNameSpecifier ListElement
|
||
| | | `-'n'
|
||
| | |-'::' ListDelimiter
|
||
| | |-SimpleTemplateNameSpecifier ListElement
|
||
| | | |-'template'
|
||
| | | |-'ST'
|
||
| | | |-'<'
|
||
| | | |-'int'
|
||
| | | `-'>'
|
||
| | `-'::' ListDelimiter
|
||
| |-'template' TemplateKeyword
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'f'
|
||
| |-'<'
|
||
| |-'int'
|
||
| `-'>'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, QualifiedId_DependentType) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
if (GetParam().hasDelayedTemplateParsing()) {
|
||
// FIXME: Make this test work on Windows by generating the expected syntax
|
||
// tree when `-fdelayed-template-parsing` is active.
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template <typename T>
|
||
void test() {
|
||
[[T::template U<int>::f()]];
|
||
[[T::U::f()]];
|
||
[[T::template f<0>()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| |-NestedNameSpecifier Qualifier
|
||
| | |-IdentifierNameSpecifier ListElement
|
||
| | | `-'T'
|
||
| | |-'::' ListDelimiter
|
||
| | |-SimpleTemplateNameSpecifier ListElement
|
||
| | | |-'template'
|
||
| | | |-'U'
|
||
| | | |-'<'
|
||
| | | |-'int'
|
||
| | | `-'>'
|
||
| | `-'::' ListDelimiter
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'f'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| |-NestedNameSpecifier Qualifier
|
||
| | |-IdentifierNameSpecifier ListElement
|
||
| | | `-'T'
|
||
| | |-'::' ListDelimiter
|
||
| | |-IdentifierNameSpecifier ListElement
|
||
| | | `-'U'
|
||
| | `-'::' ListDelimiter
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'f'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| |-NestedNameSpecifier Qualifier
|
||
| | |-IdentifierNameSpecifier ListElement
|
||
| | | `-'T'
|
||
| | `-'::' ListDelimiter
|
||
| |-'template' TemplateKeyword
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'f'
|
||
| |-'<'
|
||
| |-IntegerLiteralExpression
|
||
| | `-'0' LiteralToken
|
||
| `-'>'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, This_Simple) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
S* test(){
|
||
return [[this]];
|
||
}
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
ThisExpression ReturnValue
|
||
`-'this' IntroducerKeyword
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, This_ExplicitMemberAccess) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
int a;
|
||
void test(){
|
||
[[this->a]];
|
||
}
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
MemberExpression Expression
|
||
|-ThisExpression Object
|
||
| `-'this' IntroducerKeyword
|
||
|-'->' AccessToken
|
||
`-IdExpression Member
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, This_ImplicitMemberAccess) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
int a;
|
||
void test(){
|
||
[[a]];
|
||
}
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
IdExpression Expression
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ParenExpr) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[(1)]];
|
||
[[((1))]];
|
||
[[(1 + (2))]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ParenExpression Expression
|
||
|-'(' OpenParen
|
||
|-IntegerLiteralExpression SubExpression
|
||
| `-'1' LiteralToken
|
||
`-')' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
ParenExpression Expression
|
||
|-'(' OpenParen
|
||
|-ParenExpression SubExpression
|
||
| |-'(' OpenParen
|
||
| |-IntegerLiteralExpression SubExpression
|
||
| | `-'1' LiteralToken
|
||
| `-')' CloseParen
|
||
`-')' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
ParenExpression Expression
|
||
|-'(' OpenParen
|
||
|-BinaryOperatorExpression SubExpression
|
||
| |-IntegerLiteralExpression LeftHandSide
|
||
| | `-'1' LiteralToken
|
||
| |-'+' OperatorToken
|
||
| `-ParenExpression RightHandSide
|
||
| |-'(' OpenParen
|
||
| |-IntegerLiteralExpression SubExpression
|
||
| | `-'2' LiteralToken
|
||
| `-')' CloseParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Char) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
unsigned operator "" _c(char);
|
||
void test() {
|
||
[['2'_c]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CharUserDefinedLiteralExpression Expression
|
||
`-''2'_c' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_String) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
typedef decltype(sizeof(void *)) size_t;
|
||
|
||
unsigned operator "" _s(const char*, size_t);
|
||
|
||
void test() {
|
||
[["12"_s]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
StringUserDefinedLiteralExpression Expression
|
||
`-'"12"_s' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Integer) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
unsigned operator "" _i(unsigned long long);
|
||
unsigned operator "" _r(const char*);
|
||
template <char...>
|
||
unsigned operator "" _t();
|
||
|
||
void test() {
|
||
[[12_i]];
|
||
[[12_r]];
|
||
[[12_t]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
IntegerUserDefinedLiteralExpression Expression
|
||
`-'12_i' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
IntegerUserDefinedLiteralExpression Expression
|
||
`-'12_r' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
IntegerUserDefinedLiteralExpression Expression
|
||
`-'12_t' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Float) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
unsigned operator "" _f(long double);
|
||
unsigned operator "" _r(const char*);
|
||
template <char...>
|
||
unsigned operator "" _t();
|
||
|
||
void test() {
|
||
[[1.2_f]];
|
||
[[1.2_r]];
|
||
[[1.2_t]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
FloatUserDefinedLiteralExpression Expression
|
||
`-'1.2_f' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
FloatUserDefinedLiteralExpression Expression
|
||
`-'1.2_r' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
FloatUserDefinedLiteralExpression Expression
|
||
`-'1.2_t' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, IntegerLiteral_LongLong) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[12ll]];
|
||
[[12ull]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
IntegerLiteralExpression Expression
|
||
`-'12ll' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
IntegerLiteralExpression Expression
|
||
`-'12ull' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, IntegerLiteral_Binary) {
|
||
if (!GetParam().isCXX14OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[0b1100]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
IntegerLiteralExpression Expression
|
||
`-'0b1100' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, IntegerLiteral_WithDigitSeparators) {
|
||
if (!GetParam().isCXX14OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[1'2'0ull]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
IntegerLiteralExpression Expression
|
||
`-'1'2'0ull' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CharacterLiteral) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[['a']];
|
||
[['\n']];
|
||
[['\x20']];
|
||
[['\0']];
|
||
[[L'a']];
|
||
[[L'α']];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-''a'' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-''\n'' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-''\x20'' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-''\0'' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-'L'a'' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-'L'α'' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CharacterLiteral_Utf) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[u'a']];
|
||
[[u'構']];
|
||
[[U'a']];
|
||
[[U'🌲']];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-'u'a'' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-'u'構'' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-'U'a'' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-'U'🌲'' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CharacterLiteral_Utf8) {
|
||
if (!GetParam().isCXX17OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[u8'a']];
|
||
[[u8'\x7f']];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-'u8'a'' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
CharacterLiteralExpression Expression
|
||
`-'u8'\x7f'' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, FloatingLiteral) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[1e-2]];
|
||
[[2.]];
|
||
[[.2]];
|
||
[[2.f]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
FloatingLiteralExpression Expression
|
||
`-'1e-2' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
FloatingLiteralExpression Expression
|
||
`-'2.' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
FloatingLiteralExpression Expression
|
||
`-'.2' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
FloatingLiteralExpression Expression
|
||
`-'2.f' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, FloatingLiteral_Hexadecimal) {
|
||
if (!GetParam().isCXX17OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[0xfp1]];
|
||
[[0xf.p1]];
|
||
[[0x.fp1]];
|
||
[[0xf.fp1f]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
FloatingLiteralExpression Expression
|
||
`-'0xfp1' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
FloatingLiteralExpression Expression
|
||
`-'0xf.p1' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
FloatingLiteralExpression Expression
|
||
`-'0x.fp1' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
FloatingLiteralExpression Expression
|
||
`-'0xf.fp1f' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, StringLiteral) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[["a\n\0\x20"]];
|
||
[[L"αβ"]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
StringLiteralExpression Expression
|
||
`-'"a\n\0\x20"' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
StringLiteralExpression Expression
|
||
`-'L"αβ"' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, StringLiteral_Utf) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[u8"a\x1f\x05"]];
|
||
[[u"C++抽象構文木"]];
|
||
[[U"📖🌲\n"]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
StringLiteralExpression Expression
|
||
`-'u8"a\x1f\x05"' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
StringLiteralExpression Expression
|
||
`-'u"C++抽象構文木"' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
StringLiteralExpression Expression
|
||
`-'U"📖🌲\n"' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, StringLiteral_Raw) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
// This test uses regular string literals instead of raw string literals to
|
||
// hold source code and expected output because of a bug in MSVC up to MSVC
|
||
// 2019 16.2:
|
||
// https://developercommunity.visualstudio.com/content/problem/67300/stringifying-raw-string-literal.html
|
||
EXPECT_TRUE(treeDumpEqual( //
|
||
"void test() {\n"
|
||
" R\"SyntaxTree(\n"
|
||
" Hello \"Syntax\" \\\"\n"
|
||
" )SyntaxTree\";\n"
|
||
"}\n",
|
||
"TranslationUnit Detached\n"
|
||
"`-SimpleDeclaration\n"
|
||
" |-'void'\n"
|
||
" |-DeclaratorList Declarators\n"
|
||
" | `-SimpleDeclarator ListElement\n"
|
||
" | |-'test'\n"
|
||
" | `-ParametersAndQualifiers\n"
|
||
" | |-'(' OpenParen\n"
|
||
" | `-')' CloseParen\n"
|
||
" `-CompoundStatement\n"
|
||
" |-'{' OpenParen\n"
|
||
" |-ExpressionStatement Statement\n"
|
||
" | |-StringLiteralExpression Expression\n"
|
||
" | | `-'R\"SyntaxTree(\n"
|
||
" Hello \"Syntax\" \\\"\n"
|
||
" )SyntaxTree\"' LiteralToken\n"
|
||
" | `-';'\n"
|
||
" `-'}' CloseParen\n"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, BoolLiteral) {
|
||
if (GetParam().isC()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[true]];
|
||
[[false]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BoolLiteralExpression Expression
|
||
`-'true' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BoolLiteralExpression Expression
|
||
`-'false' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CxxNullPtrLiteral) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[nullptr]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CxxNullPtrExpression Expression
|
||
`-'nullptr' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, PostfixUnaryOperator) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test(int a) {
|
||
[[a++]];
|
||
[[a--]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
PostfixUnaryOperatorExpression Expression
|
||
|-IdExpression Operand
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'a'
|
||
`-'++' OperatorToken
|
||
)txt",
|
||
R"txt(
|
||
PostfixUnaryOperatorExpression Expression
|
||
|-IdExpression Operand
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'a'
|
||
`-'--' OperatorToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, PrefixUnaryOperator) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test(int a, int *ap) {
|
||
[[--a]]; [[++a]];
|
||
[[~a]];
|
||
[[-a]];
|
||
[[+a]];
|
||
[[&a]];
|
||
[[*ap]];
|
||
[[!a]];
|
||
[[__real a]]; [[__imag a]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'--' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt",
|
||
R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'++' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt",
|
||
R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'~' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt",
|
||
R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'-' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt",
|
||
R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'+' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt",
|
||
R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'&' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt",
|
||
R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'*' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'ap'
|
||
)txt",
|
||
R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'!' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt",
|
||
R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'__real' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt",
|
||
R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'__imag' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, PrefixUnaryOperatorCxx) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test(int a, bool b) {
|
||
[[compl a]];
|
||
[[not b]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'compl' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt",
|
||
R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'not' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'b'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, BinaryOperator) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test(int a) {
|
||
[[1 - 2]];
|
||
[[1 == 2]];
|
||
[[a = 1]];
|
||
[[a <<= 1]];
|
||
[[1 || 0]];
|
||
[[1 & 2]];
|
||
[[a != 3]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IntegerLiteralExpression LeftHandSide
|
||
| `-'1' LiteralToken
|
||
|-'-' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'2' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IntegerLiteralExpression LeftHandSide
|
||
| `-'1' LiteralToken
|
||
|-'==' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'2' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'a'
|
||
|-'=' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'1' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'a'
|
||
|-'<<=' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'1' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IntegerLiteralExpression LeftHandSide
|
||
| `-'1' LiteralToken
|
||
|-'||' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'0' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IntegerLiteralExpression LeftHandSide
|
||
| `-'1' LiteralToken
|
||
|-'&' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'2' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'a'
|
||
|-'!=' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'3' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, BinaryOperatorCxx) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test(int a) {
|
||
[[true || false]];
|
||
[[true or false]];
|
||
[[1 bitand 2]];
|
||
[[a xor_eq 3]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-BoolLiteralExpression LeftHandSide
|
||
| `-'true' LiteralToken
|
||
|-'||' OperatorToken
|
||
`-BoolLiteralExpression RightHandSide
|
||
`-'false' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-BoolLiteralExpression LeftHandSide
|
||
| `-'true' LiteralToken
|
||
|-'or' OperatorToken
|
||
`-BoolLiteralExpression RightHandSide
|
||
`-'false' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IntegerLiteralExpression LeftHandSide
|
||
| `-'1' LiteralToken
|
||
|-'bitand' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'2' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'a'
|
||
|-'xor_eq' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'3' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, BinaryOperator_NestedWithParenthesis) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[(1 + 2) * (4 / 2)]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-ParenExpression LeftHandSide
|
||
| |-'(' OpenParen
|
||
| |-BinaryOperatorExpression SubExpression
|
||
| | |-IntegerLiteralExpression LeftHandSide
|
||
| | | `-'1' LiteralToken
|
||
| | |-'+' OperatorToken
|
||
| | `-IntegerLiteralExpression RightHandSide
|
||
| | `-'2' LiteralToken
|
||
| `-')' CloseParen
|
||
|-'*' OperatorToken
|
||
`-ParenExpression RightHandSide
|
||
|-'(' OpenParen
|
||
|-BinaryOperatorExpression SubExpression
|
||
| |-IntegerLiteralExpression LeftHandSide
|
||
| | `-'4' LiteralToken
|
||
| |-'/' OperatorToken
|
||
| `-IntegerLiteralExpression RightHandSide
|
||
| `-'2' LiteralToken
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, BinaryOperator_Associativity) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test(int a, int b) {
|
||
[[a + b + 42]];
|
||
[[a = b = 42]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-BinaryOperatorExpression LeftHandSide
|
||
| |-IdExpression LeftHandSide
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'a'
|
||
| |-'+' OperatorToken
|
||
| `-IdExpression RightHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'b'
|
||
|-'+' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'42' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'a'
|
||
|-'=' OperatorToken
|
||
`-BinaryOperatorExpression RightHandSide
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'b'
|
||
|-'=' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'42' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, BinaryOperator_Precedence) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void test() {
|
||
[[1 + 2 * 3 + 4]];
|
||
[[1 % 2 + 3 * 4]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-BinaryOperatorExpression LeftHandSide
|
||
| |-IntegerLiteralExpression LeftHandSide
|
||
| | `-'1' LiteralToken
|
||
| |-'+' OperatorToken
|
||
| `-BinaryOperatorExpression RightHandSide
|
||
| |-IntegerLiteralExpression LeftHandSide
|
||
| | `-'2' LiteralToken
|
||
| |-'*' OperatorToken
|
||
| `-IntegerLiteralExpression RightHandSide
|
||
| `-'3' LiteralToken
|
||
|-'+' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'4' LiteralToken
|
||
)txt",
|
||
R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-BinaryOperatorExpression LeftHandSide
|
||
| |-IntegerLiteralExpression LeftHandSide
|
||
| | `-'1' LiteralToken
|
||
| |-'%' OperatorToken
|
||
| `-IntegerLiteralExpression RightHandSide
|
||
| `-'2' LiteralToken
|
||
|-'+' OperatorToken
|
||
`-BinaryOperatorExpression RightHandSide
|
||
|-IntegerLiteralExpression LeftHandSide
|
||
| `-'3' LiteralToken
|
||
|-'*' OperatorToken
|
||
`-IntegerLiteralExpression RightHandSide
|
||
`-'4' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Assignment) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X& operator=(const X&);
|
||
};
|
||
void test(X x, X y) {
|
||
[[x = y]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'x'
|
||
|-'=' OperatorToken
|
||
`-IdExpression RightHandSide
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'y'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Plus) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
friend X operator+(X, const X&);
|
||
};
|
||
void test(X x, X y) {
|
||
[[x + y]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'x'
|
||
|-'+' OperatorToken
|
||
`-IdExpression RightHandSide
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'y'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Less) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
friend bool operator<(const X&, const X&);
|
||
};
|
||
void test(X x, X y) {
|
||
[[x < y]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'x'
|
||
|-'<' OperatorToken
|
||
`-IdExpression RightHandSide
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'y'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperator_LeftShift) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
friend X operator<<(X&, const X&);
|
||
};
|
||
void test(X x, X y) {
|
||
[[x << y]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'x'
|
||
|-'<<' OperatorToken
|
||
`-IdExpression RightHandSide
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'y'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Comma) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X operator,(X&);
|
||
};
|
||
void test(X x, X y) {
|
||
[[x, y]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'x'
|
||
|-',' OperatorToken
|
||
`-IdExpression RightHandSide
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'y'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PointerToMember) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X operator->*(int);
|
||
};
|
||
void test(X* xp, int X::* pmi) {
|
||
[[xp->*pmi]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
BinaryOperatorExpression Expression
|
||
|-IdExpression LeftHandSide
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'xp'
|
||
|-'->*' OperatorToken
|
||
`-IdExpression RightHandSide
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'pmi'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Negation) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
bool operator!();
|
||
};
|
||
void test(X x) {
|
||
[[!x]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'!' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'x'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperator_AddressOf) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X* operator&();
|
||
};
|
||
void test(X x) {
|
||
[[&x]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'&' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'x'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PrefixIncrement) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X operator++();
|
||
};
|
||
void test(X x) {
|
||
[[++x]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
PrefixUnaryOperatorExpression Expression
|
||
|-'++' OperatorToken
|
||
`-IdExpression Operand
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'x'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PostfixIncrement) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X operator++(int);
|
||
};
|
||
void test(X x) {
|
||
[[x++]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
PostfixUnaryOperatorExpression Expression
|
||
|-IdExpression Operand
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'x'
|
||
`-'++' OperatorToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MemberExpression_SimpleWithDot) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
int a;
|
||
};
|
||
void test(struct S s) {
|
||
[[s.a]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
MemberExpression Expression
|
||
|-IdExpression Object
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'s'
|
||
|-'.' AccessToken
|
||
`-IdExpression Member
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MemberExpression_StaticDataMember) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
static int a;
|
||
};
|
||
void test(S s) {
|
||
[[s.a]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
MemberExpression Expression
|
||
|-IdExpression Object
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'s'
|
||
|-'.' AccessToken
|
||
`-IdExpression Member
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MemberExpression_SimpleWithArrow) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
int a;
|
||
};
|
||
void test(struct S* sp) {
|
||
[[sp->a]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
MemberExpression Expression
|
||
|-IdExpression Object
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'sp'
|
||
|-'->' AccessToken
|
||
`-IdExpression Member
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'a'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MemberExpression_Chaining) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
struct S* next;
|
||
};
|
||
void test(struct S s){
|
||
[[s.next->next]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
MemberExpression Expression
|
||
|-MemberExpression Object
|
||
| |-IdExpression Object
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'s'
|
||
| |-'.' AccessToken
|
||
| `-IdExpression Member
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'next'
|
||
|-'->' AccessToken
|
||
`-IdExpression Member
|
||
`-UnqualifiedId UnqualifiedId
|
||
`-'next'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MemberExpression_OperatorFunction) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
bool operator!();
|
||
};
|
||
void test(S s) {
|
||
[[s.operator!()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-IdExpression Object
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'s'
|
||
| |-'.' AccessToken
|
||
| `-IdExpression Member
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'operator'
|
||
| `-'!'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MemberExpression_VariableTemplate) {
|
||
if (!GetParam().isCXX14OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
template<typename T>
|
||
static constexpr T x = 42;
|
||
};
|
||
// FIXME: `<int>` should be a child of `MemberExpression` and `;` of
|
||
// `ExpressionStatement`. This is a bug in clang, in `getSourceRange` methods.
|
||
void test(S s) [[{
|
||
s.x<int>;
|
||
}]]
|
||
)cpp",
|
||
{R"txt(
|
||
CompoundStatement
|
||
|-'{' OpenParen
|
||
|-ExpressionStatement Statement
|
||
| `-MemberExpression Expression
|
||
| |-IdExpression Object
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'s'
|
||
| |-'.' AccessToken
|
||
| `-IdExpression Member
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'x'
|
||
|-'<'
|
||
|-'int'
|
||
|-'>'
|
||
|-';'
|
||
`-'}' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MemberExpression_FunctionTemplate) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
template<typename T>
|
||
T f();
|
||
};
|
||
void test(S* sp){
|
||
[[sp->f<int>()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-IdExpression Object
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'sp'
|
||
| |-'->' AccessToken
|
||
| `-IdExpression Member
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'f'
|
||
| |-'<'
|
||
| |-'int'
|
||
| `-'>'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest,
|
||
MemberExpression_FunctionTemplateWithTemplateKeyword) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
template<typename T>
|
||
T f();
|
||
};
|
||
void test(S s){
|
||
[[s.template f<int>()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-IdExpression Object
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'s'
|
||
| |-'.' AccessToken
|
||
| |-'template'
|
||
| `-IdExpression Member
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'f'
|
||
| |-'<'
|
||
| |-'int'
|
||
| `-'>'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MemberExpression_WithQualifier) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct Base {
|
||
void f();
|
||
};
|
||
struct S : public Base {};
|
||
void test(S s){
|
||
[[s.Base::f()]];
|
||
[[s.::S::~S()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-IdExpression Object
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'s'
|
||
| |-'.' AccessToken
|
||
| `-IdExpression Member
|
||
| |-NestedNameSpecifier Qualifier
|
||
| | |-IdentifierNameSpecifier ListElement
|
||
| | | `-'Base'
|
||
| | `-'::' ListDelimiter
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'f'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-IdExpression Object
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'s'
|
||
| |-'.' AccessToken
|
||
| `-IdExpression Member
|
||
| |-NestedNameSpecifier Qualifier
|
||
| | |-'::' ListDelimiter
|
||
| | |-IdentifierNameSpecifier ListElement
|
||
| | | `-'S'
|
||
| | `-'::' ListDelimiter
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'~'
|
||
| `-'S'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MemberExpression_Complex) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template<typename T>
|
||
struct U {
|
||
template<typename U>
|
||
U f();
|
||
};
|
||
struct S {
|
||
U<int> getU();
|
||
};
|
||
void test(S* sp) {
|
||
// FIXME: The first 'template' keyword is a child of `NestedNameSpecifier`,
|
||
// but it should be a child of `MemberExpression` according to the grammar.
|
||
// However one might argue that the 'template' keyword fits better inside
|
||
// `NestedNameSpecifier` because if we change `U<int>` to `UI` we would like
|
||
// equally to change the `NameSpecifier` `template U<int>` to just `UI`.
|
||
[[sp->getU().template U<int>::template f<int>()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-CallExpression Object
|
||
| | |-MemberExpression Callee
|
||
| | | |-IdExpression Object
|
||
| | | | `-UnqualifiedId UnqualifiedId
|
||
| | | | `-'sp'
|
||
| | | |-'->' AccessToken
|
||
| | | `-IdExpression Member
|
||
| | | `-UnqualifiedId UnqualifiedId
|
||
| | | `-'getU'
|
||
| | |-'(' OpenParen
|
||
| | `-')' CloseParen
|
||
| |-'.' AccessToken
|
||
| `-IdExpression Member
|
||
| |-NestedNameSpecifier Qualifier
|
||
| | |-SimpleTemplateNameSpecifier ListElement
|
||
| | | |-'template'
|
||
| | | |-'U'
|
||
| | | |-'<'
|
||
| | | |-'int'
|
||
| | | `-'>'
|
||
| | `-'::' ListDelimiter
|
||
| |-'template' TemplateKeyword
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| |-'f'
|
||
| |-'<'
|
||
| |-'int'
|
||
| `-'>'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_Member) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S{
|
||
void f();
|
||
};
|
||
void test(S s) {
|
||
[[s.f()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-IdExpression Object
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'s'
|
||
| |-'.' AccessToken
|
||
| `-IdExpression Member
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'f'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParens) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
void operator()();
|
||
};
|
||
void test(S s) {
|
||
[[s()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'s'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParensChaining) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
S operator()();
|
||
};
|
||
void test(S s) {
|
||
[[s()()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-CallExpression Callee
|
||
| |-IdExpression Callee
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'s'
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberWithThis) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct Base {
|
||
void f();
|
||
};
|
||
struct S: public Base {
|
||
void f();
|
||
void test() {
|
||
[[this->f()]];
|
||
[[f()]];
|
||
[[this->Base::f()]];
|
||
}
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-ThisExpression Object
|
||
| | `-'this' IntroducerKeyword
|
||
| |-'->' AccessToken
|
||
| `-IdExpression Member
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'f'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'f'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
CallExpression Expression
|
||
|-MemberExpression Callee
|
||
| |-ThisExpression Object
|
||
| | `-'this' IntroducerKeyword
|
||
| |-'->' AccessToken
|
||
| `-IdExpression Member
|
||
| |-NestedNameSpecifier Qualifier
|
||
| | |-IdentifierNameSpecifier ListElement
|
||
| | | `-'Base'
|
||
| | `-'::' ListDelimiter
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'f'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_FunctionPointer) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void (*pf)();
|
||
void test() {
|
||
[[pf()]];
|
||
[[(*pf)()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'pf'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
CallExpression Expression
|
||
|-ParenExpression Callee
|
||
| |-'(' OpenParen
|
||
| |-PrefixUnaryOperatorExpression SubExpression
|
||
| | |-'*' OperatorToken
|
||
| | `-IdExpression Operand
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'pf'
|
||
| `-')' CloseParen
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberFunctionPointer) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
void f();
|
||
};
|
||
void test(S s) {
|
||
void (S::*pmf)();
|
||
pmf = &S::f;
|
||
[[(s.*pmf)()]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-ParenExpression Callee
|
||
| |-'(' OpenParen
|
||
| |-BinaryOperatorExpression SubExpression
|
||
| | |-IdExpression LeftHandSide
|
||
| | | `-UnqualifiedId UnqualifiedId
|
||
| | | `-'s'
|
||
| | |-'.*' OperatorToken
|
||
| | `-IdExpression RightHandSide
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'pmf'
|
||
| `-')' CloseParen
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Zero) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void f();
|
||
void test() {
|
||
[[f();]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ExpressionStatement Statement
|
||
|-CallExpression Expression
|
||
| |-IdExpression Callee
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'f'
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_One) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void f(int);
|
||
void test() {
|
||
[[f(1);]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ExpressionStatement Statement
|
||
|-CallExpression Expression
|
||
| |-IdExpression Callee
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'f'
|
||
| |-'(' OpenParen
|
||
| |-CallArguments Arguments
|
||
| | `-IntegerLiteralExpression ListElement
|
||
| | `-'1' LiteralToken
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Multiple) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void f(int, char, float);
|
||
void test() {
|
||
[[f(1, '2', 3.);]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ExpressionStatement Statement
|
||
|-CallExpression Expression
|
||
| |-IdExpression Callee
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'f'
|
||
| |-'(' OpenParen
|
||
| |-CallArguments Arguments
|
||
| | |-IntegerLiteralExpression ListElement
|
||
| | | `-'1' LiteralToken
|
||
| | |-',' ListDelimiter
|
||
| | |-CharacterLiteralExpression ListElement
|
||
| | | `-''2'' LiteralToken
|
||
| | |-',' ListDelimiter
|
||
| | `-FloatingLiteralExpression ListElement
|
||
| | `-'3.' LiteralToken
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Assignment) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void f(int);
|
||
void test(int a) {
|
||
[[f(a = 1);]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ExpressionStatement Statement
|
||
|-CallExpression Expression
|
||
| |-IdExpression Callee
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'f'
|
||
| |-'(' OpenParen
|
||
| |-CallArguments Arguments
|
||
| | `-BinaryOperatorExpression ListElement
|
||
| | |-IdExpression LeftHandSide
|
||
| | | `-UnqualifiedId UnqualifiedId
|
||
| | | `-'a'
|
||
| | |-'=' OperatorToken
|
||
| | `-IntegerLiteralExpression RightHandSide
|
||
| | `-'1' LiteralToken
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Empty) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void f(int[]);
|
||
void test() {
|
||
[[f({});]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ExpressionStatement Statement
|
||
|-CallExpression Expression
|
||
| |-IdExpression Callee
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'f'
|
||
| |-'(' OpenParen
|
||
| |-CallArguments Arguments
|
||
| | `-UnknownExpression ListElement
|
||
| | `-UnknownExpression
|
||
| | |-'{'
|
||
| | `-'}'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Simple) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct TT {};
|
||
struct T{
|
||
int a;
|
||
TT b;
|
||
};
|
||
void f(T);
|
||
void test() {
|
||
[[f({1, {}});]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ExpressionStatement Statement
|
||
|-CallExpression Expression
|
||
| |-IdExpression Callee
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'f'
|
||
| |-'(' OpenParen
|
||
| |-CallArguments Arguments
|
||
| | `-UnknownExpression ListElement
|
||
| | `-UnknownExpression
|
||
| | |-'{'
|
||
| | |-IntegerLiteralExpression
|
||
| | | `-'1' LiteralToken
|
||
| | |-','
|
||
| | |-UnknownExpression
|
||
| | | `-UnknownExpression
|
||
| | | |-'{'
|
||
| | | `-'}'
|
||
| | `-'}'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest,
|
||
CallExpression_Arguments_BracedInitList_Designated) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct TT {};
|
||
struct T{
|
||
int a;
|
||
TT b;
|
||
};
|
||
void f(T);
|
||
void test() {
|
||
[[f({.a = 1, .b {}});]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ExpressionStatement Statement
|
||
|-CallExpression Expression
|
||
| |-IdExpression Callee
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'f'
|
||
| |-'(' OpenParen
|
||
| |-CallArguments Arguments
|
||
| | `-UnknownExpression ListElement
|
||
| | `-UnknownExpression
|
||
| | |-'{'
|
||
| | |-UnknownExpression
|
||
| | | |-'.'
|
||
| | | |-'a'
|
||
| | | |-'='
|
||
| | | `-IntegerLiteralExpression
|
||
| | | `-'1' LiteralToken
|
||
| | |-','
|
||
| | |-UnknownExpression
|
||
| | | |-'.'
|
||
| | | |-'b'
|
||
| | | `-UnknownExpression
|
||
| | | `-UnknownExpression
|
||
| | | |-'{'
|
||
| | | `-'}'
|
||
| | `-'}'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_ParameterPack) {
|
||
if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template<typename T, typename... Args>
|
||
void test(T t, Args... args) {
|
||
[[test(args...)]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-UnknownExpression Callee
|
||
| `-'test'
|
||
|-'(' OpenParen
|
||
|-CallArguments Arguments
|
||
| `-UnknownExpression ListElement
|
||
| |-IdExpression
|
||
| | `-UnqualifiedId UnqualifiedId
|
||
| | `-'args'
|
||
| `-'...'
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, CallExpression_DefaultArguments) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
void f(int i = 1, char c = '2');
|
||
void test() {
|
||
[[f()]];
|
||
[[f(1)]];
|
||
[[f(1, '2')]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'f'
|
||
|-'(' OpenParen
|
||
`-')' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'f'
|
||
|-'(' OpenParen
|
||
|-CallArguments Arguments
|
||
| `-IntegerLiteralExpression ListElement
|
||
| `-'1' LiteralToken
|
||
`-')' CloseParen
|
||
)txt",
|
||
R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'f'
|
||
|-'(' OpenParen
|
||
|-CallArguments Arguments
|
||
| |-IntegerLiteralExpression ListElement
|
||
| | `-'1' LiteralToken
|
||
| |-',' ListDelimiter
|
||
| `-CharacterLiteralExpression ListElement
|
||
| `-''2'' LiteralToken
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGrouping) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int *a, b;
|
||
int *c, d;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | |-SimpleDeclarator ListElement
|
||
| | | |-'*'
|
||
| | | `-'a'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'b'
|
||
| `-';'
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| |-SimpleDeclarator ListElement
|
||
| | |-'*'
|
||
| | `-'c'
|
||
| |-',' ListDelimiter
|
||
| `-SimpleDeclarator ListElement
|
||
| `-'d'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGroupingTypedef) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
typedef int *a, b;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'typedef'
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| |-SimpleDeclarator ListElement
|
||
| | |-'*'
|
||
| | `-'a'
|
||
| |-',' ListDelimiter
|
||
| `-SimpleDeclarator ListElement
|
||
| `-'b'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsInsideStatement) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
void foo() {
|
||
int *a, b;
|
||
typedef int *ta, tb;
|
||
}
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'foo'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-CompoundStatement
|
||
|-'{' OpenParen
|
||
|-DeclarationStatement Statement
|
||
| |-SimpleDeclaration
|
||
| | |-'int'
|
||
| | `-DeclaratorList Declarators
|
||
| | |-SimpleDeclarator ListElement
|
||
| | | |-'*'
|
||
| | | `-'a'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'b'
|
||
| `-';'
|
||
|-DeclarationStatement Statement
|
||
| |-SimpleDeclaration
|
||
| | |-'typedef'
|
||
| | |-'int'
|
||
| | `-DeclaratorList Declarators
|
||
| | |-SimpleDeclarator ListElement
|
||
| | | |-'*'
|
||
| | | `-'ta'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'tb'
|
||
| `-';'
|
||
`-'}' CloseParen
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, SizeTTypedef) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
typedef decltype(sizeof(void *)) size_t;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'typedef'
|
||
|-'decltype'
|
||
|-'('
|
||
|-UnknownExpression
|
||
| |-'sizeof'
|
||
| |-'('
|
||
| |-'void'
|
||
| |-'*'
|
||
| `-')'
|
||
|-')'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| `-'size_t'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Namespace_Nested) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
namespace a { namespace b {} }
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-NamespaceDefinition
|
||
|-'namespace'
|
||
|-'a'
|
||
|-'{'
|
||
|-NamespaceDefinition
|
||
| |-'namespace'
|
||
| |-'b'
|
||
| |-'{'
|
||
| `-'}'
|
||
`-'}'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Namespace_NestedDefinition) {
|
||
if (!GetParam().isCXX17OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
namespace a::b {}
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-NamespaceDefinition
|
||
|-'namespace'
|
||
|-'a'
|
||
|-'::'
|
||
|-'b'
|
||
|-'{'
|
||
`-'}'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Namespace_Unnamed) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
namespace {}
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-NamespaceDefinition
|
||
|-'namespace'
|
||
|-'{'
|
||
`-'}'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Namespace_Alias) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
namespace a {}
|
||
[[namespace foo = a;]]
|
||
)cpp",
|
||
{R"txt(
|
||
NamespaceAliasDefinition
|
||
|-'namespace'
|
||
|-'foo'
|
||
|-'='
|
||
|-'a'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UsingDirective) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
namespace ns {}
|
||
[[using namespace ::ns;]]
|
||
)cpp",
|
||
{R"txt(
|
||
UsingNamespaceDirective
|
||
|-'using'
|
||
|-'namespace'
|
||
|-NestedNameSpecifier
|
||
| `-'::' ListDelimiter
|
||
|-'ns'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UsingDeclaration_Namespace) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
namespace ns { int a; }
|
||
[[using ns::a;]]
|
||
)cpp",
|
||
{R"txt(
|
||
UsingDeclaration
|
||
|-'using'
|
||
|-NestedNameSpecifier
|
||
| |-IdentifierNameSpecifier ListElement
|
||
| | `-'ns'
|
||
| `-'::' ListDelimiter
|
||
|-'a'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UsingDeclaration_ClassMember) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template <class T> struct X {
|
||
[[using T::foo;]]
|
||
[[using typename T::bar;]]
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
UsingDeclaration
|
||
|-'using'
|
||
|-NestedNameSpecifier
|
||
| |-IdentifierNameSpecifier ListElement
|
||
| | `-'T'
|
||
| `-'::' ListDelimiter
|
||
|-'foo'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
UsingDeclaration
|
||
|-'using'
|
||
|-'typename'
|
||
|-NestedNameSpecifier
|
||
| |-IdentifierNameSpecifier ListElement
|
||
| | `-'T'
|
||
| `-'::' ListDelimiter
|
||
|-'bar'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, UsingTypeAlias) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
using type = int;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-TypeAliasDeclaration
|
||
|-'using'
|
||
|-'type'
|
||
|-'='
|
||
|-'int'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, FreeStandingClass_ForwardDeclaration) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
[[struct X;]]
|
||
[[struct Y *y1;]]
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'struct'
|
||
|-'X'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'struct'
|
||
|-'Y'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'*'
|
||
| `-'y1'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, FreeStandingClasses_Definition) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
[[struct X {};]]
|
||
[[struct Y {} *y2;]]
|
||
[[struct {} *a1;]]
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'struct'
|
||
|-'X'
|
||
|-'{'
|
||
|-'}'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'struct'
|
||
|-'Y'
|
||
|-'{'
|
||
|-'}'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'*'
|
||
| `-'y2'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'struct'
|
||
|-'{'
|
||
|-'}'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'*'
|
||
| `-'a1'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, StaticMemberFunction) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
[[static void f(){}]]
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'static'
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'f'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-CompoundStatement
|
||
|-'{' OpenParen
|
||
`-'}' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OutOfLineMemberFunctionDefinition) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
void f();
|
||
};
|
||
[[void S::f(){}]]
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-NestedNameSpecifier
|
||
| | |-IdentifierNameSpecifier ListElement
|
||
| | | `-'S'
|
||
| | `-'::' ListDelimiter
|
||
| |-'f'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-CompoundStatement
|
||
|-'{' OpenParen
|
||
`-'}' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ConversionMemberFunction) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
[[operator int();]]
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'operator'
|
||
| |-'int'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, LiteralOperatorDeclaration) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
unsigned operator "" _c(char);
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'unsigned'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'operator'
|
||
| |-'""'
|
||
| |-'_c'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | `-SimpleDeclaration ListElement
|
||
| | `-'char'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
template <char...>
|
||
unsigned operator "" _t();
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-TemplateDeclaration Declaration
|
||
|-'template' IntroducerKeyword
|
||
|-'<'
|
||
|-SimpleDeclaration
|
||
| `-'char'
|
||
|-'...'
|
||
|-'>'
|
||
`-SimpleDeclaration
|
||
|-'unsigned'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'operator'
|
||
| |-'""'
|
||
| |-'_t'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperatorDeclaration) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
[[X& operator=(const X&);]]
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'X'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'&'
|
||
| |-'operator'
|
||
| |-'='
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'const'
|
||
| | |-'X'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'&'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, OverloadedOperatorFriendDeclaration) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
[[friend X operator+(X, const X&);]]
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
UnknownDeclaration
|
||
`-SimpleDeclaration
|
||
|-'friend'
|
||
|-'X'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'operator'
|
||
| |-'+'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | `-'X'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'const'
|
||
| | |-'X'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'&'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ClassTemplateDeclaration) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
template<typename T>
|
||
struct ST {};
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-TemplateDeclaration Declaration
|
||
|-'template' IntroducerKeyword
|
||
|-'<'
|
||
|-UnknownDeclaration
|
||
| |-'typename'
|
||
| `-'T'
|
||
|-'>'
|
||
`-SimpleDeclaration
|
||
|-'struct'
|
||
|-'ST'
|
||
|-'{'
|
||
|-'}'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, FunctionTemplateDeclaration) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
template<typename T>
|
||
T f();
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-TemplateDeclaration Declaration
|
||
|-'template' IntroducerKeyword
|
||
|-'<'
|
||
|-UnknownDeclaration
|
||
| |-'typename'
|
||
| `-'T'
|
||
|-'>'
|
||
`-SimpleDeclaration
|
||
|-'T'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'f'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, VariableTemplateDeclaration) {
|
||
if (!GetParam().isCXX14OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
template <class T> T var = 10;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-TemplateDeclaration Declaration
|
||
|-'template' IntroducerKeyword
|
||
|-'<'
|
||
|-UnknownDeclaration
|
||
| |-'class'
|
||
| `-'T'
|
||
|-'>'
|
||
`-SimpleDeclaration
|
||
|-'T'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'var'
|
||
| |-'='
|
||
| `-IntegerLiteralExpression
|
||
| `-'10' LiteralToken
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, StaticMemberFunctionTemplate) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
[[template<typename U>
|
||
static U f();]]
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
TemplateDeclaration Declaration
|
||
|-'template' IntroducerKeyword
|
||
|-'<'
|
||
|-UnknownDeclaration
|
||
| |-'typename'
|
||
| `-'U'
|
||
|-'>'
|
||
`-SimpleDeclaration
|
||
|-'static'
|
||
|-'U'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'f'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, NestedTemplates) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
template <class T>
|
||
struct X {
|
||
template <class U>
|
||
U foo();
|
||
};
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-TemplateDeclaration Declaration
|
||
|-'template' IntroducerKeyword
|
||
|-'<'
|
||
|-UnknownDeclaration
|
||
| |-'class'
|
||
| `-'T'
|
||
|-'>'
|
||
`-SimpleDeclaration
|
||
|-'struct'
|
||
|-'X'
|
||
|-'{'
|
||
|-TemplateDeclaration Declaration
|
||
| |-'template' IntroducerKeyword
|
||
| |-'<'
|
||
| |-UnknownDeclaration
|
||
| | |-'class'
|
||
| | `-'U'
|
||
| |-'>'
|
||
| `-SimpleDeclaration
|
||
| |-'U'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'foo'
|
||
| | `-ParametersAndQualifiers
|
||
| | |-'(' OpenParen
|
||
| | `-')' CloseParen
|
||
| `-';'
|
||
|-'}'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, NestedTemplatesInNamespace) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
namespace n {
|
||
template<typename T>
|
||
struct ST {
|
||
template<typename U>
|
||
static U f();
|
||
};
|
||
}
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-NamespaceDefinition
|
||
|-'namespace'
|
||
|-'n'
|
||
|-'{'
|
||
|-TemplateDeclaration Declaration
|
||
| |-'template' IntroducerKeyword
|
||
| |-'<'
|
||
| |-UnknownDeclaration
|
||
| | |-'typename'
|
||
| | `-'T'
|
||
| |-'>'
|
||
| `-SimpleDeclaration
|
||
| |-'struct'
|
||
| |-'ST'
|
||
| |-'{'
|
||
| |-TemplateDeclaration Declaration
|
||
| | |-'template' IntroducerKeyword
|
||
| | |-'<'
|
||
| | |-UnknownDeclaration
|
||
| | | |-'typename'
|
||
| | | `-'U'
|
||
| | |-'>'
|
||
| | `-SimpleDeclaration
|
||
| | |-'static'
|
||
| | |-'U'
|
||
| | |-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | |-'f'
|
||
| | | `-ParametersAndQualifiers
|
||
| | | |-'(' OpenParen
|
||
| | | `-')' CloseParen
|
||
| | `-';'
|
||
| |-'}'
|
||
| `-';'
|
||
`-'}'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ClassTemplate_MemberClassDefinition) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template <class T> struct X { struct Y; };
|
||
[[template <class T> struct X<T>::Y {};]]
|
||
)cpp",
|
||
{R"txt(
|
||
TemplateDeclaration Declaration
|
||
|-'template' IntroducerKeyword
|
||
|-'<'
|
||
|-UnknownDeclaration
|
||
| |-'class'
|
||
| `-'T'
|
||
|-'>'
|
||
`-SimpleDeclaration
|
||
|-'struct'
|
||
|-NestedNameSpecifier
|
||
| |-SimpleTemplateNameSpecifier ListElement
|
||
| | |-'X'
|
||
| | |-'<'
|
||
| | |-'T'
|
||
| | `-'>'
|
||
| `-'::' ListDelimiter
|
||
|-'Y'
|
||
|-'{'
|
||
|-'}'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Definition) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template <class T> struct X {};
|
||
[[template struct X<double>;]]
|
||
)cpp",
|
||
{R"txt(
|
||
ExplicitTemplateInstantiation
|
||
|-'template' IntroducerKeyword
|
||
`-SimpleDeclaration Declaration
|
||
|-'struct'
|
||
|-'X'
|
||
|-'<'
|
||
|-'double'
|
||
|-'>'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Declaration) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template <class T> struct X {};
|
||
[[extern template struct X<float>;]]
|
||
)cpp",
|
||
{R"txt(
|
||
ExplicitTemplateInstantiation
|
||
|-'extern' ExternKeyword
|
||
|-'template' IntroducerKeyword
|
||
`-SimpleDeclaration Declaration
|
||
|-'struct'
|
||
|-'X'
|
||
|-'<'
|
||
|-'float'
|
||
|-'>'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Partial) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template <class T> struct X {};
|
||
[[template <class T> struct X<T*> {};]]
|
||
)cpp",
|
||
{R"txt(
|
||
TemplateDeclaration Declaration
|
||
|-'template' IntroducerKeyword
|
||
|-'<'
|
||
|-UnknownDeclaration
|
||
| |-'class'
|
||
| `-'T'
|
||
|-'>'
|
||
`-SimpleDeclaration
|
||
|-'struct'
|
||
|-'X'
|
||
|-'<'
|
||
|-'T'
|
||
|-'*'
|
||
|-'>'
|
||
|-'{'
|
||
|-'}'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Full) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template <class T> struct X {};
|
||
[[template <> struct X<int> {};]]
|
||
)cpp",
|
||
{R"txt(
|
||
TemplateDeclaration Declaration
|
||
|-'template' IntroducerKeyword
|
||
|-'<'
|
||
|-'>'
|
||
`-SimpleDeclaration
|
||
|-'struct'
|
||
|-'X'
|
||
|-'<'
|
||
|-'int'
|
||
|-'>'
|
||
|-'{'
|
||
|-'}'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, EmptyDeclaration) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-EmptyDeclaration
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, StaticAssert) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
static_assert(true, "message");
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-StaticAssertDeclaration
|
||
|-'static_assert'
|
||
|-'('
|
||
|-BoolLiteralExpression Condition
|
||
| `-'true' LiteralToken
|
||
|-','
|
||
|-StringLiteralExpression Message
|
||
| `-'"message"' LiteralToken
|
||
|-')'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, StaticAssert_WithoutMessage) {
|
||
if (!GetParam().isCXX17OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
static_assert(true);
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-StaticAssertDeclaration
|
||
|-'static_assert'
|
||
|-'('
|
||
|-BoolLiteralExpression Condition
|
||
| `-'true' LiteralToken
|
||
|-')'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ExternC) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
extern "C" int a;
|
||
extern "C" { int b; int c; }
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
|-LinkageSpecificationDeclaration
|
||
| |-'extern'
|
||
| |-'"C"'
|
||
| `-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'a'
|
||
| `-';'
|
||
`-LinkageSpecificationDeclaration
|
||
|-'extern'
|
||
|-'"C"'
|
||
|-'{'
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'b'
|
||
| `-';'
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'c'
|
||
| `-';'
|
||
`-'}'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_Leaf) {
|
||
// All nodes can be mutated.
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
#define OPEN {
|
||
#define CLOSE }
|
||
|
||
void test() {
|
||
OPEN
|
||
1;
|
||
CLOSE
|
||
|
||
OPEN
|
||
2;
|
||
}
|
||
}
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'test'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-CompoundStatement
|
||
|-'{' OpenParen
|
||
|-CompoundStatement Statement
|
||
| |-'{' OpenParen
|
||
| |-ExpressionStatement Statement
|
||
| | |-IntegerLiteralExpression Expression
|
||
| | | `-'1' LiteralToken
|
||
| | `-';'
|
||
| `-'}' CloseParen
|
||
|-CompoundStatement Statement
|
||
| |-'{' OpenParen
|
||
| |-ExpressionStatement Statement
|
||
| | |-IntegerLiteralExpression Expression
|
||
| | | `-'2' LiteralToken
|
||
| | `-';'
|
||
| `-'}' CloseParen
|
||
`-'}' CloseParen
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MatchTree) {
|
||
// Some nodes are unmodifiable, they are marked with 'unmodifiable'.
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
#define BRACES {}
|
||
|
||
void test() BRACES
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'test'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-CompoundStatement
|
||
|-'{' OpenParen unmodifiable
|
||
`-'}' CloseParen unmodifiable
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MismatchTree) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
#define HALF_IF if (1+
|
||
#define HALF_IF_2 1) {}
|
||
void test() {
|
||
HALF_IF HALF_IF_2 else {}
|
||
})cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'test'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-CompoundStatement
|
||
|-'{' OpenParen
|
||
|-IfStatement Statement
|
||
| |-'if' IntroducerKeyword unmodifiable
|
||
| |-'(' unmodifiable
|
||
| |-BinaryOperatorExpression unmodifiable
|
||
| | |-IntegerLiteralExpression LeftHandSide unmodifiable
|
||
| | | `-'1' LiteralToken unmodifiable
|
||
| | |-'+' OperatorToken unmodifiable
|
||
| | `-IntegerLiteralExpression RightHandSide unmodifiable
|
||
| | `-'1' LiteralToken unmodifiable
|
||
| |-')' unmodifiable
|
||
| |-CompoundStatement ThenStatement unmodifiable
|
||
| | |-'{' OpenParen unmodifiable
|
||
| | `-'}' CloseParen unmodifiable
|
||
| |-'else' ElseKeyword
|
||
| `-CompoundStatement ElseStatement
|
||
| |-'{' OpenParen
|
||
| `-'}' CloseParen
|
||
`-'}' CloseParen
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_ModifiableArguments) {
|
||
// FIXME: Note that the substitutions for `X` and `Y` are marked modifiable.
|
||
// However we cannot change `X` freely. Indeed if we change its substitution
|
||
// in the condition we should also change it the then-branch.
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
#define MIN(X,Y) X < Y ? X : Y
|
||
|
||
void test() {
|
||
MIN(1,2);
|
||
}
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'test'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-CompoundStatement
|
||
|-'{' OpenParen
|
||
|-ExpressionStatement Statement
|
||
| |-UnknownExpression Expression
|
||
| | |-BinaryOperatorExpression unmodifiable
|
||
| | | |-IntegerLiteralExpression LeftHandSide
|
||
| | | | `-'1' LiteralToken
|
||
| | | |-'<' OperatorToken unmodifiable
|
||
| | | `-IntegerLiteralExpression RightHandSide
|
||
| | | `-'2' LiteralToken
|
||
| | |-'?' unmodifiable
|
||
| | |-IntegerLiteralExpression
|
||
| | | `-'1' LiteralToken
|
||
| | |-':' unmodifiable
|
||
| | `-IntegerLiteralExpression
|
||
| | `-'2' LiteralToken
|
||
| `-';'
|
||
`-'}' CloseParen
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_MismatchTree) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
#define HALF_IF(X) if (X &&
|
||
#define HALF_IF_2(Y) Y) {}
|
||
void test() {
|
||
HALF_IF(1) HALF_IF_2(0) else {}
|
||
})cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'test'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-CompoundStatement
|
||
|-'{' OpenParen
|
||
|-IfStatement Statement
|
||
| |-'if' IntroducerKeyword unmodifiable
|
||
| |-'(' unmodifiable
|
||
| |-BinaryOperatorExpression unmodifiable
|
||
| | |-IntegerLiteralExpression LeftHandSide
|
||
| | | `-'1' LiteralToken
|
||
| | |-'&&' OperatorToken unmodifiable
|
||
| | `-IntegerLiteralExpression RightHandSide
|
||
| | `-'0' LiteralToken
|
||
| |-')' unmodifiable
|
||
| |-CompoundStatement ThenStatement unmodifiable
|
||
| | |-'{' OpenParen unmodifiable
|
||
| | `-'}' CloseParen unmodifiable
|
||
| |-'else' ElseKeyword
|
||
| `-CompoundStatement ElseStatement
|
||
| |-'{' OpenParen
|
||
| `-'}' CloseParen
|
||
`-'}' CloseParen
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_Variadic) {
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
#define CALL(F_NAME, ...) F_NAME(__VA_ARGS__)
|
||
|
||
void f(int);
|
||
void g(int, int);
|
||
void test() [[{
|
||
CALL(f, 0);
|
||
CALL(g, 0, 1);
|
||
}]]
|
||
)cpp",
|
||
{R"txt(
|
||
CompoundStatement
|
||
|-'{' OpenParen
|
||
|-ExpressionStatement Statement
|
||
| |-CallExpression Expression
|
||
| | |-IdExpression Callee
|
||
| | | `-UnqualifiedId UnqualifiedId
|
||
| | | `-'f'
|
||
| | |-'(' OpenParen unmodifiable
|
||
| | |-CallArguments Arguments
|
||
| | | `-IntegerLiteralExpression ListElement
|
||
| | | `-'0' LiteralToken
|
||
| | `-')' CloseParen unmodifiable
|
||
| `-';'
|
||
|-ExpressionStatement Statement
|
||
| |-CallExpression Expression
|
||
| | |-IdExpression Callee
|
||
| | | `-UnqualifiedId UnqualifiedId
|
||
| | | `-'g'
|
||
| | |-'(' OpenParen unmodifiable
|
||
| | |-CallArguments Arguments
|
||
| | | |-IntegerLiteralExpression ListElement
|
||
| | | | `-'0' LiteralToken
|
||
| | | |-',' ListDelimiter
|
||
| | | `-IntegerLiteralExpression ListElement
|
||
| | | `-'1' LiteralToken
|
||
| | `-')' CloseParen unmodifiable
|
||
| `-';'
|
||
`-'}' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, InitDeclarator_Equal) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S { S(int);};
|
||
void test() {
|
||
[[S s = 1]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
|-'s'
|
||
|-'='
|
||
`-IntegerLiteralExpression
|
||
`-'1' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, InitDeclarator_Brace) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
S();
|
||
S(int);
|
||
S(int, float);
|
||
};
|
||
void test(){
|
||
// FIXME: 's...' is a declarator and '{...}' is initializer
|
||
[[S s0{}]];
|
||
[[S s1{1}]];
|
||
[[S s2{1, 2.}]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
`-UnknownExpression
|
||
|-'s0'
|
||
|-'{'
|
||
`-'}'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
`-UnknownExpression
|
||
|-'s1'
|
||
|-'{'
|
||
|-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
`-'}'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
`-UnknownExpression
|
||
|-'s2'
|
||
|-'{'
|
||
|-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
|-','
|
||
|-FloatingLiteralExpression
|
||
| `-'2.' LiteralToken
|
||
`-'}'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, InitDeclarator_EqualBrace) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
S();
|
||
S(int);
|
||
S(int, float);
|
||
};
|
||
void test() {
|
||
// FIXME: '= {...}' is initializer
|
||
[[S s0 = {}]];
|
||
[[S s1 = {1}]];
|
||
[[S s2 = {1, 2.}]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
|-'s0'
|
||
|-'='
|
||
`-UnknownExpression
|
||
|-'{'
|
||
`-'}'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
|-'s1'
|
||
|-'='
|
||
`-UnknownExpression
|
||
|-'{'
|
||
|-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
`-'}'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
|-'s2'
|
||
|-'='
|
||
`-UnknownExpression
|
||
|-'{'
|
||
|-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
|-','
|
||
|-FloatingLiteralExpression
|
||
| `-'2.' LiteralToken
|
||
`-'}'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
S(int);
|
||
S(int, float);
|
||
};
|
||
// FIXME: 's...' is a declarator and '(...)' is initializer
|
||
[[S s1(1);]]
|
||
[[S s2(1, 2.);]]
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| `-UnknownExpression
|
||
| |-'s1'
|
||
| |-'('
|
||
| |-IntegerLiteralExpression
|
||
| | `-'1' LiteralToken
|
||
| `-')'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| `-UnknownExpression
|
||
| |-'s2'
|
||
| |-'('
|
||
| |-IntegerLiteralExpression
|
||
| | `-'1' LiteralToken
|
||
| |-','
|
||
| |-FloatingLiteralExpression
|
||
| | `-'2.' LiteralToken
|
||
| `-')'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren_DefaultArguments) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct S {
|
||
S(int i = 1, float = 2.);
|
||
};
|
||
[[S s0;]]
|
||
// FIXME: 's...' is a declarator and '(...)' is initializer
|
||
[[S s1(1);]]
|
||
[[S s2(1, 2.);]]
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| `-'s0'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| `-UnknownExpression
|
||
| |-'s1'
|
||
| |-'('
|
||
| |-IntegerLiteralExpression
|
||
| | `-'1' LiteralToken
|
||
| `-')'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'S'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| `-UnknownExpression
|
||
| |-'s2'
|
||
| |-'('
|
||
| |-IntegerLiteralExpression
|
||
| | `-'1' LiteralToken
|
||
| |-','
|
||
| |-FloatingLiteralExpression
|
||
| | `-'2.' LiteralToken
|
||
| `-')'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Argument) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X(int);
|
||
};
|
||
void TakeX(const X&);
|
||
void test() {
|
||
[[TakeX(1)]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
CallExpression Expression
|
||
|-IdExpression Callee
|
||
| `-UnqualifiedId UnqualifiedId
|
||
| `-'TakeX'
|
||
|-'(' OpenParen
|
||
|-CallArguments Arguments
|
||
| `-IntegerLiteralExpression ListElement
|
||
| `-'1' LiteralToken
|
||
`-')' CloseParen
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Return) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X(int);
|
||
};
|
||
X CreateX(){
|
||
[[return 1;]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ReturnStatement Statement
|
||
|-'return' IntroducerKeyword
|
||
|-IntegerLiteralExpression ReturnValue
|
||
| `-'1' LiteralToken
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ConstructorCall_ZeroArguments) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X();
|
||
};
|
||
X test() {
|
||
[[return X();]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ReturnStatement Statement
|
||
|-'return' IntroducerKeyword
|
||
|-UnknownExpression ReturnValue
|
||
| |-'X'
|
||
| |-'('
|
||
| `-')'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ConstructorCall_OneArgument) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X(int);
|
||
};
|
||
X test() {
|
||
[[return X(1);]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ReturnStatement Statement
|
||
|-'return' IntroducerKeyword
|
||
|-UnknownExpression ReturnValue
|
||
| |-'X'
|
||
| |-'('
|
||
| |-IntegerLiteralExpression
|
||
| | `-'1' LiteralToken
|
||
| `-')'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ConstructorCall_MultipleArguments) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X(int, char);
|
||
};
|
||
X test() {
|
||
[[return X(1, '2');]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ReturnStatement Statement
|
||
|-'return' IntroducerKeyword
|
||
|-UnknownExpression ReturnValue
|
||
| |-'X'
|
||
| |-'('
|
||
| |-IntegerLiteralExpression
|
||
| | `-'1' LiteralToken
|
||
| |-','
|
||
| |-CharacterLiteralExpression
|
||
| | `-''2'' LiteralToken
|
||
| `-')'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ConstructorCall_DefaultArguments) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
X(int i = 1, char c = '2');
|
||
};
|
||
X test() {
|
||
auto x0 = [[X()]];
|
||
auto x1 = [[X(1)]];
|
||
auto x2 = [[X(1, '2')]];
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
UnknownExpression
|
||
|-'X'
|
||
|-'('
|
||
`-')'
|
||
)txt",
|
||
R"txt(
|
||
UnknownExpression
|
||
|-'X'
|
||
|-'('
|
||
|-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
`-')'
|
||
)txt",
|
||
R"txt(
|
||
UnknownExpression
|
||
|-'X'
|
||
|-'('
|
||
|-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
|-','
|
||
|-CharacterLiteralExpression
|
||
| `-''2'' LiteralToken
|
||
`-')'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, TypeConversion_FunctionalNotation) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
float test() {
|
||
[[return float(1);]]
|
||
}
|
||
)cpp",
|
||
{R"txt(
|
||
ReturnStatement Statement
|
||
|-'return' IntroducerKeyword
|
||
|-UnknownExpression ReturnValue
|
||
| |-'float'
|
||
| |-'('
|
||
| |-IntegerLiteralExpression
|
||
| | `-'1' LiteralToken
|
||
| `-')'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Simple) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int a[10];
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'a'
|
||
| `-ArraySubscript
|
||
| |-'[' OpenParen
|
||
| |-IntegerLiteralExpression Size
|
||
| | `-'10' LiteralToken
|
||
| `-']' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Multidimensional) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int b[1][2][3];
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'b'
|
||
| |-ArraySubscript
|
||
| | |-'[' OpenParen
|
||
| | |-IntegerLiteralExpression Size
|
||
| | | `-'1' LiteralToken
|
||
| | `-']' CloseParen
|
||
| |-ArraySubscript
|
||
| | |-'[' OpenParen
|
||
| | |-IntegerLiteralExpression Size
|
||
| | | `-'2' LiteralToken
|
||
| | `-']' CloseParen
|
||
| `-ArraySubscript
|
||
| |-'[' OpenParen
|
||
| |-IntegerLiteralExpression Size
|
||
| | `-'3' LiteralToken
|
||
| `-']' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_UnknownBound) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int c[] = {1,2,3};
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'c'
|
||
| |-ArraySubscript
|
||
| | |-'[' OpenParen
|
||
| | `-']' CloseParen
|
||
| |-'='
|
||
| `-UnknownExpression
|
||
| `-UnknownExpression
|
||
| |-'{'
|
||
| |-IntegerLiteralExpression
|
||
| | `-'1' LiteralToken
|
||
| |-','
|
||
| |-IntegerLiteralExpression
|
||
| | `-'2' LiteralToken
|
||
| |-','
|
||
| |-IntegerLiteralExpression
|
||
| | `-'3' LiteralToken
|
||
| `-'}'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Static) {
|
||
if (!GetParam().isC99OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
void f(int xs[static 10]);
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'f'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'int'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'xs'
|
||
| | `-ArraySubscript
|
||
| | |-'[' OpenParen
|
||
| | |-'static'
|
||
| | |-IntegerLiteralExpression Size
|
||
| | | `-'10' LiteralToken
|
||
| | `-']' CloseParen
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int func();
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'func'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int func1(int a);
|
||
int func2(int *ap);
|
||
int func3(int a, float b);
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'func1'
|
||
| | `-ParametersAndQualifiers
|
||
| | |-'(' OpenParen
|
||
| | |-ParameterDeclarationList Parameters
|
||
| | | `-SimpleDeclaration ListElement
|
||
| | | |-'int'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | `-'a'
|
||
| | `-')' CloseParen
|
||
| `-';'
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'func2'
|
||
| | `-ParametersAndQualifiers
|
||
| | |-'(' OpenParen
|
||
| | |-ParameterDeclarationList Parameters
|
||
| | | `-SimpleDeclaration ListElement
|
||
| | | |-'int'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | |-'*'
|
||
| | | `-'ap'
|
||
| | `-')' CloseParen
|
||
| `-';'
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'func3'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | |-'int'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | `-'a'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'float'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'b'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int func1(int);
|
||
int func2(int *);
|
||
int func3(int, float);
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'func1'
|
||
| | `-ParametersAndQualifiers
|
||
| | |-'(' OpenParen
|
||
| | |-ParameterDeclarationList Parameters
|
||
| | | `-SimpleDeclaration ListElement
|
||
| | | `-'int'
|
||
| | `-')' CloseParen
|
||
| `-';'
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'func2'
|
||
| | `-ParametersAndQualifiers
|
||
| | |-'(' OpenParen
|
||
| | |-ParameterDeclarationList Parameters
|
||
| | | `-SimpleDeclaration ListElement
|
||
| | | |-'int'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | `-'*'
|
||
| | `-')' CloseParen
|
||
| `-';'
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'func3'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | `-'int'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclaration ListElement
|
||
| | `-'float'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest,
|
||
ParametersAndQualifiers_InFreeFunctions_Default_One) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
int func1([[int a = 1]]);
|
||
)cpp",
|
||
{R"txt(
|
||
ParameterDeclarationList Parameters
|
||
`-SimpleDeclaration ListElement
|
||
|-'int'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
|-'a'
|
||
|-'='
|
||
`-IntegerLiteralExpression
|
||
`-'1' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest,
|
||
ParametersAndQualifiers_InFreeFunctions_Default_Multiple) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
int func2([[int *ap, int a = 1, char c = '2']]);
|
||
)cpp",
|
||
{R"txt(
|
||
ParameterDeclarationList Parameters
|
||
|-SimpleDeclaration ListElement
|
||
| |-'int'
|
||
| `-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'*'
|
||
| `-'ap'
|
||
|-',' ListDelimiter
|
||
|-SimpleDeclaration ListElement
|
||
| |-'int'
|
||
| `-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'a'
|
||
| |-'='
|
||
| `-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
|-',' ListDelimiter
|
||
`-SimpleDeclaration ListElement
|
||
|-'char'
|
||
`-DeclaratorList Declarators
|
||
`-SimpleDeclarator ListElement
|
||
|-'c'
|
||
|-'='
|
||
`-CharacterLiteralExpression
|
||
`-''2'' LiteralToken
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest,
|
||
ParametersAndQualifiers_InVariadicFunctionTemplate_ParameterPack) {
|
||
if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template<typename T, typename... Args>
|
||
[[void test(T , Args... );]]
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'test'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | `-'T'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'Args'
|
||
| | `-'...'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest,
|
||
ParametersAndQualifiers_InVariadicFunctionTemplate_NamedParameterPack) {
|
||
if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
template<typename T, typename... Args>
|
||
[[void test(T t, Args... args);]]
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'test'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | |-'T'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | `-'t'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'Args'
|
||
| | |-'...'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'args'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest,
|
||
ParametersAndQualifiers_InFreeFunctions_VariadicArguments) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
void test(int , char ...);
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'test'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | `-'int'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclaration ListElement
|
||
| | `-'char'
|
||
| |-'...'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest,
|
||
ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int func(const int a, volatile int b, const volatile int c);
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'func'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | |-'const'
|
||
| | | |-'int'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | `-'a'
|
||
| | |-',' ListDelimiter
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | |-'volatile'
|
||
| | | |-'int'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | `-'b'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'const'
|
||
| | |-'volatile'
|
||
| | |-'int'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'c'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int func(int& a);
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'func'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'int'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'&'
|
||
| | `-'a'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest,
|
||
ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int func(int&& a);
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'func'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'int'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'&&'
|
||
| | `-'a'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
struct Test {
|
||
int a();
|
||
};
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'struct'
|
||
|-'Test'
|
||
|-'{'
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'a'
|
||
| | `-ParametersAndQualifiers
|
||
| | |-'(' OpenParen
|
||
| | `-')' CloseParen
|
||
| `-';'
|
||
|-'}'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest,
|
||
ParametersAndQualifiers_InMemberFunctions_CvQualifiers) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct Test {
|
||
[[int b() const;]]
|
||
[[int c() volatile;]]
|
||
[[int d() const volatile;]]
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'b'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| `-'const'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'c'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| `-'volatile'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'d'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| |-'const'
|
||
| `-'volatile'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct Test {
|
||
[[int e() &;]]
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'e'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| `-'&'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct Test {
|
||
[[int f() &&;]]
|
||
};
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'f'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| `-'&&'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, TrailingReturn) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
auto foo() -> int;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'auto'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'foo'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| `-TrailingReturnType TrailingReturn
|
||
| |-'->' ArrowToken
|
||
| `-'int'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, DynamicExceptionSpecification) {
|
||
if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct MyException1 {};
|
||
struct MyException2 {};
|
||
[[int a() throw();]]
|
||
[[int b() throw(...);]]
|
||
[[int c() throw(MyException1);]]
|
||
[[int d() throw(MyException1, MyException2);]]
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'a'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| |-'throw'
|
||
| |-'('
|
||
| `-')'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'b'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| |-'throw'
|
||
| |-'('
|
||
| |-'...'
|
||
| `-')'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'c'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| |-'throw'
|
||
| |-'('
|
||
| |-'MyException1'
|
||
| `-')'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'d'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| |-'throw'
|
||
| |-'('
|
||
| |-'MyException1'
|
||
| |-','
|
||
| |-'MyException2'
|
||
| `-')'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, NoexceptExceptionSpecification) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int a() noexcept;
|
||
int b() noexcept(true);
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'a'
|
||
| | `-ParametersAndQualifiers
|
||
| | |-'(' OpenParen
|
||
| | |-')' CloseParen
|
||
| | `-'noexcept'
|
||
| `-';'
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'b'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| |-'noexcept'
|
||
| |-'('
|
||
| |-BoolLiteralExpression
|
||
| | `-'true' LiteralToken
|
||
| `-')'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, DeclaratorsInParentheses) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
int (a);
|
||
int *(b);
|
||
int (*c)(int);
|
||
int *(d)(int);
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-ParenDeclarator
|
||
| | |-'(' OpenParen
|
||
| | |-'a'
|
||
| | `-')' CloseParen
|
||
| `-';'
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'*'
|
||
| | `-ParenDeclarator
|
||
| | |-'(' OpenParen
|
||
| | |-'b'
|
||
| | `-')' CloseParen
|
||
| `-';'
|
||
|-SimpleDeclaration
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-ParenDeclarator
|
||
| | | |-'(' OpenParen
|
||
| | | |-'*'
|
||
| | | |-'c'
|
||
| | | `-')' CloseParen
|
||
| | `-ParametersAndQualifiers
|
||
| | |-'(' OpenParen
|
||
| | |-ParameterDeclarationList Parameters
|
||
| | | `-SimpleDeclaration ListElement
|
||
| | | `-'int'
|
||
| | `-')' CloseParen
|
||
| `-';'
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'*'
|
||
| |-ParenDeclarator
|
||
| | |-'(' OpenParen
|
||
| | |-'d'
|
||
| | `-')' CloseParen
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | `-SimpleDeclaration ListElement
|
||
| | `-'int'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
const int west = -1;
|
||
int const east = 1;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
|-SimpleDeclaration
|
||
| |-'const'
|
||
| |-'int'
|
||
| |-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-'west'
|
||
| | |-'='
|
||
| | `-PrefixUnaryOperatorExpression
|
||
| | |-'-' OperatorToken
|
||
| | `-IntegerLiteralExpression Operand
|
||
| | `-'1' LiteralToken
|
||
| `-';'
|
||
`-SimpleDeclaration
|
||
|-'int'
|
||
|-'const'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'east'
|
||
| |-'='
|
||
| `-IntegerLiteralExpression
|
||
| `-'1' LiteralToken
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
const int const universal = 0;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'const'
|
||
|-'int'
|
||
|-'const'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'universal'
|
||
| |-'='
|
||
| `-IntegerLiteralExpression
|
||
| `-'0' LiteralToken
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest,
|
||
Declaration_ConstVolatileQualifiers_ConstAndVolatile) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
const int const *const *volatile b;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'const'
|
||
|-'int'
|
||
|-'const'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'*'
|
||
| |-'const'
|
||
| |-'*'
|
||
| |-'volatile'
|
||
| `-'b'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) {
|
||
if (!GetParam().isCXX11OrLater()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
auto foo() -> auto(*)(int) -> double*;
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'auto'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'foo'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-')' CloseParen
|
||
| `-TrailingReturnType TrailingReturn
|
||
| |-'->' ArrowToken
|
||
| |-'auto'
|
||
| `-SimpleDeclarator Declarator
|
||
| |-ParenDeclarator
|
||
| | |-'(' OpenParen
|
||
| | |-'*'
|
||
| | `-')' CloseParen
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | `-SimpleDeclaration ListElement
|
||
| | `-'int'
|
||
| |-')' CloseParen
|
||
| `-TrailingReturnType TrailingReturn
|
||
| |-'->' ArrowToken
|
||
| |-'double'
|
||
| `-SimpleDeclarator Declarator
|
||
| `-'*'
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MemberPointers) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {};
|
||
[[int X::* a;]]
|
||
[[const int X::* b;]]
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-MemberPointer
|
||
| | |-'X'
|
||
| | |-'::'
|
||
| | `-'*'
|
||
| `-'a'
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'const'
|
||
|-'int'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-MemberPointer
|
||
| | |-'X'
|
||
| | |-'::'
|
||
| | `-'*'
|
||
| `-'b'
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, MemberFunctionPointer) {
|
||
if (!GetParam().isCXX()) {
|
||
return;
|
||
}
|
||
EXPECT_TRUE(treeDumpEqualOnAnnotations(
|
||
R"cpp(
|
||
struct X {
|
||
struct Y {};
|
||
};
|
||
[[void (X::*xp)();]]
|
||
[[void (X::**xpp)(const int*);]]
|
||
// FIXME: Generate the right syntax tree for this type,
|
||
// i.e. create a syntax node for the outer member pointer
|
||
[[void (X::Y::*xyp)(const int*, char);]]
|
||
)cpp",
|
||
{R"txt(
|
||
SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-ParenDeclarator
|
||
| | |-'(' OpenParen
|
||
| | |-MemberPointer
|
||
| | | |-'X'
|
||
| | | |-'::'
|
||
| | | `-'*'
|
||
| | |-'xp'
|
||
| | `-')' CloseParen
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-ParenDeclarator
|
||
| | |-'(' OpenParen
|
||
| | |-MemberPointer
|
||
| | | |-'X'
|
||
| | | |-'::'
|
||
| | | `-'*'
|
||
| | |-'*'
|
||
| | |-'xpp'
|
||
| | `-')' CloseParen
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'const'
|
||
| | |-'int'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | `-'*'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt",
|
||
R"txt(
|
||
SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-ParenDeclarator
|
||
| | |-'(' OpenParen
|
||
| | |-'X'
|
||
| | |-'::'
|
||
| | |-MemberPointer
|
||
| | | |-'Y'
|
||
| | | |-'::'
|
||
| | | `-'*'
|
||
| | |-'xyp'
|
||
| | `-')' CloseParen
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | |-'const'
|
||
| | | |-'int'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | `-'*'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclaration ListElement
|
||
| | `-'char'
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"}));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ComplexDeclarator) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
void x(char a, short (*b)(int));
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'x'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | |-'char'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | `-'a'
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'short'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-ParenDeclarator
|
||
| | | |-'(' OpenParen
|
||
| | | |-'*'
|
||
| | | |-'b'
|
||
| | | `-')' CloseParen
|
||
| | `-ParametersAndQualifiers
|
||
| | |-'(' OpenParen
|
||
| | |-ParameterDeclarationList Parameters
|
||
| | | `-SimpleDeclaration ListElement
|
||
| | | `-'int'
|
||
| | `-')' CloseParen
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
TEST_P(BuildSyntaxTreeTest, ComplexDeclarator2) {
|
||
EXPECT_TRUE(treeDumpEqual(
|
||
R"cpp(
|
||
void x(char a, short (*b)(int), long (**c)(long long));
|
||
)cpp",
|
||
R"txt(
|
||
TranslationUnit Detached
|
||
`-SimpleDeclaration
|
||
|-'void'
|
||
|-DeclaratorList Declarators
|
||
| `-SimpleDeclarator ListElement
|
||
| |-'x'
|
||
| `-ParametersAndQualifiers
|
||
| |-'(' OpenParen
|
||
| |-ParameterDeclarationList Parameters
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | |-'char'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | `-'a'
|
||
| | |-',' ListDelimiter
|
||
| | |-SimpleDeclaration ListElement
|
||
| | | |-'short'
|
||
| | | `-DeclaratorList Declarators
|
||
| | | `-SimpleDeclarator ListElement
|
||
| | | |-ParenDeclarator
|
||
| | | | |-'(' OpenParen
|
||
| | | | |-'*'
|
||
| | | | |-'b'
|
||
| | | | `-')' CloseParen
|
||
| | | `-ParametersAndQualifiers
|
||
| | | |-'(' OpenParen
|
||
| | | |-ParameterDeclarationList Parameters
|
||
| | | | `-SimpleDeclaration ListElement
|
||
| | | | `-'int'
|
||
| | | `-')' CloseParen
|
||
| | |-',' ListDelimiter
|
||
| | `-SimpleDeclaration ListElement
|
||
| | |-'long'
|
||
| | `-DeclaratorList Declarators
|
||
| | `-SimpleDeclarator ListElement
|
||
| | |-ParenDeclarator
|
||
| | | |-'(' OpenParen
|
||
| | | |-'*'
|
||
| | | |-'*'
|
||
| | | |-'c'
|
||
| | | `-')' CloseParen
|
||
| | `-ParametersAndQualifiers
|
||
| | |-'(' OpenParen
|
||
| | |-ParameterDeclarationList Parameters
|
||
| | | `-SimpleDeclaration ListElement
|
||
| | | |-'long'
|
||
| | | `-'long'
|
||
| | `-')' CloseParen
|
||
| `-')' CloseParen
|
||
`-';'
|
||
)txt"));
|
||
}
|
||
|
||
} // namespace
|