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
|