[clang] 2de2ca3 - [SyntaxTree] Add support for `CallExpression`
Eduardo Caldas via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 26 00:04:01 PDT 2020
Author: Eduardo Caldas
Date: 2020-08-26T07:03:49Z
New Revision: 2de2ca348dfa09963eb33ddf71c9cbb59612c16a
URL: https://github.com/llvm/llvm-project/commit/2de2ca348dfa09963eb33ddf71c9cbb59612c16a
DIFF: https://github.com/llvm/llvm-project/commit/2de2ca348dfa09963eb33ddf71c9cbb59612c16a.diff
LOG: [SyntaxTree] Add support for `CallExpression`
* Generate `CallExpression` syntax node for all semantic nodes inheriting from
`CallExpr` with call-expression syntax - except `CUDAKernelCallExpr`.
* Implement all the accessors
* Arguments of `CallExpression` have their own syntax node which is based on
the `List` base API
Differential Revision: https://reviews.llvm.org/D86544
Added:
Modified:
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Tooling/Syntax/Nodes.h b/clang/include/clang/Tooling/Syntax/Nodes.h
index 0b3991768008..9a14aac130b4 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -57,6 +57,7 @@ enum class NodeKind : uint16_t {
IdExpression,
MemberExpression,
ThisExpression,
+ CallExpression,
// Statements.
UnknownStatement,
@@ -103,7 +104,8 @@ enum class NodeKind : uint16_t {
GlobalNameSpecifier,
DecltypeNameSpecifier,
IdentifierNameSpecifier,
- SimpleTemplateNameSpecifier
+ SimpleTemplateNameSpecifier,
+ CallArguments
};
/// For debugging purposes.
raw_ostream &operator<<(raw_ostream &OS, NodeKind K);
@@ -179,6 +181,8 @@ enum class NodeRole : uint8_t {
MemberExpression_object,
MemberExpression_accessToken,
MemberExpression_member,
+ CallExpression_callee,
+ CallExpression_arguments,
};
/// For debugging purposes.
raw_ostream &operator<<(raw_ostream &OS, NodeRole R);
@@ -324,6 +328,37 @@ class ThisExpression final : public Expression {
Leaf *thisKeyword();
};
+/// Models arguments of a function call.
+/// call-arguments:
+/// delimited_list(expression, ',')
+/// Note: This construct is a simplification of the grammar rule for
+/// `expression-list`, that is used in the definition of `call-expression`
+class CallArguments final : public List {
+public:
+ CallArguments() : List(NodeKind::CallArguments) {}
+ static bool classof(const Node *N) {
+ return N->kind() <= NodeKind::CallArguments;
+ }
+ std::vector<Expression *> arguments();
+ std::vector<List::ElementAndDelimiter<Expression>> argumentsAndCommas();
+};
+
+/// A function call. C++ [expr.call]
+/// call-expression:
+/// expression '(' call-arguments ')'
+/// e.g `f(1, '2')` or `this->Base::f()`
+class CallExpression final : public Expression {
+public:
+ CallExpression() : Expression(NodeKind::CallExpression) {}
+ static bool classof(const Node *N) {
+ return N->kind() == NodeKind::CallExpression;
+ }
+ Expression *callee();
+ Leaf *openParen();
+ CallArguments *arguments();
+ Leaf *closeParen();
+};
+
/// Models a parenthesized expression `(E)`. C++ [expr.prim.paren]
/// e.g. `(3 + 2)` in `a = 1 + (3 + 2);`
class ParenExpression final : public Expression {
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index f027a60030b7..2e3dbc6c6fbd 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -184,10 +184,11 @@ static syntax::NodeKind getOperatorNodeKind(const CXXOperatorCallExpr &E) {
case OO_Array_New:
case OO_Array_Delete:
case OO_Coawait:
- case OO_Call:
case OO_Subscript:
case OO_Arrow:
return syntax::NodeKind::UnknownExpression;
+ case OO_Call:
+ return syntax::NodeKind::CallExpression;
case OO_Conditional: // not overloadable
case NUM_OVERLOADED_OPERATORS:
case OO_None:
@@ -1042,6 +1043,46 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
return true;
}
+ syntax::CallArguments *buildCallArguments(CallExpr::arg_range Args) {
+ for (const auto &Arg : Args) {
+ Builder.markExprChild(Arg, syntax::NodeRole::List_element);
+ const auto *DelimiterToken =
+ std::next(Builder.findToken(Arg->getEndLoc()));
+ if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
+ Builder.markChildToken(DelimiterToken,
+ syntax::NodeRole::List_delimiter);
+ }
+
+ auto *Arguments = new (allocator()) syntax::CallArguments;
+ if (!Args.empty())
+ Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(),
+ (*(Args.end() - 1))->getEndLoc()),
+ Arguments, nullptr);
+
+ return Arguments;
+ }
+
+ bool WalkUpFromCallExpr(CallExpr *S) {
+ Builder.markExprChild(S->getCallee(),
+ syntax::NodeRole::CallExpression_callee);
+
+ const auto *LParenToken =
+ std::next(Builder.findToken(S->getCallee()->getEndLoc()));
+ // FIXME: Assert that `LParenToken` is indeed a `l_paren` once we have fixed
+ // the test on decltype desctructors.
+ if (LParenToken->kind() == clang::tok::l_paren)
+ Builder.markChildToken(LParenToken, syntax::NodeRole::OpenParen);
+
+ Builder.markChild(buildCallArguments(S->arguments()),
+ syntax::NodeRole::CallExpression_arguments);
+
+ Builder.markChildToken(S->getRParenLoc(), syntax::NodeRole::CloseParen);
+
+ Builder.foldNode(Builder.getRange(S->getSourceRange()),
+ new (allocator()) syntax::CallExpression, S);
+ return true;
+ }
+
bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
// To construct a syntax tree of the same shape for calls to built-in and
// user-defined operators, ignore the `DeclRefExpr` that refers to the
@@ -1100,8 +1141,29 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
new (allocator()) syntax::PostfixUnaryOperatorExpression,
S);
return true;
+ case syntax::NodeKind::CallExpression: {
+ Builder.markExprChild(S->getArg(0),
+ syntax::NodeRole::CallExpression_callee);
+
+ const auto *LParenToken =
+ std::next(Builder.findToken(S->getArg(0)->getEndLoc()));
+ // FIXME: Assert that `LParenToken` is indeed a `l_paren` once we have
+ // fixed the test on decltype desctructors.
+ if (LParenToken->kind() == clang::tok::l_paren)
+ Builder.markChildToken(LParenToken, syntax::NodeRole::OpenParen);
+
+ Builder.markChild(buildCallArguments(CallExpr::arg_range(
+ S->arg_begin() + 1, S->arg_end())),
+ syntax::NodeRole::CallExpression_arguments);
+
+ Builder.markChildToken(S->getRParenLoc(), syntax::NodeRole::CloseParen);
+
+ Builder.foldNode(Builder.getRange(S->getSourceRange()),
+ new (allocator()) syntax::CallExpression, S);
+ return true;
+ }
case syntax::NodeKind::UnknownExpression:
- return RecursiveASTVisitor::WalkUpFromCXXOperatorCallExpr(S);
+ return WalkUpFromExpr(S);
default:
llvm_unreachable("getOperatorNodeKind() does not return this value");
}
diff --git a/clang/lib/Tooling/Syntax/Nodes.cpp b/clang/lib/Tooling/Syntax/Nodes.cpp
index ecd4c4dac728..6a7be0f0ea79 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -52,6 +52,8 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeKind K) {
return OS << "UnqualifiedId";
case NodeKind::IdExpression:
return OS << "IdExpression";
+ case NodeKind::CallExpression:
+ return OS << "CallExpression";
case NodeKind::UnknownStatement:
return OS << "UnknownStatement";
case NodeKind::DeclarationStatement:
@@ -130,6 +132,8 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeKind K) {
return OS << "NestedNameSpecifier";
case NodeKind::MemberExpression:
return OS << "MemberExpression";
+ case NodeKind::CallArguments:
+ return OS << "CallArguments";
}
llvm_unreachable("unknown node kind");
}
@@ -212,6 +216,10 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeRole R) {
return OS << "MemberExpression_accessToken";
case syntax::NodeRole::MemberExpression_member:
return OS << "MemberExpression_member";
+ case syntax::NodeRole::CallExpression_callee:
+ return OS << "CallExpression_callee";
+ case syntax::NodeRole::CallExpression_arguments:
+ return OS << "CallExpression_arguments";
}
llvm_unreachable("invalid role");
}
@@ -240,6 +248,27 @@ syntax::NestedNameSpecifier::specifiersAndDoubleColons() {
return Children;
}
+std::vector<syntax::Expression *> syntax::CallArguments::arguments() {
+ auto ArgumentsAsNodes = getElementsAsNodes();
+ std::vector<syntax::Expression *> Children;
+ for (const auto &ArgumentAsNode : ArgumentsAsNodes) {
+ Children.push_back(llvm::cast<syntax::Expression>(ArgumentAsNode));
+ }
+ return Children;
+}
+
+std::vector<syntax::List::ElementAndDelimiter<syntax::Expression>>
+syntax::CallArguments::argumentsAndCommas() {
+ auto ArgumentsAsNodesAndCommas = getElementsAsNodesAndDelimiters();
+ std::vector<syntax::List::ElementAndDelimiter<syntax::Expression>> Children;
+ for (const auto &ArgumentAsNodeAndComma : ArgumentsAsNodesAndCommas) {
+ Children.push_back(
+ {llvm::cast<syntax::Expression>(ArgumentAsNodeAndComma.element),
+ ArgumentAsNodeAndComma.delimiter});
+ }
+ return Children;
+}
+
syntax::Expression *syntax::MemberExpression::object() {
return cast_or_null<syntax::Expression>(
findChild(syntax::NodeRole::MemberExpression_object));
@@ -322,6 +351,24 @@ syntax::Expression *syntax::BinaryOperatorExpression::rhs() {
findChild(syntax::NodeRole::BinaryOperatorExpression_rightHandSide));
}
+syntax::Expression *syntax::CallExpression::callee() {
+ return cast_or_null<syntax::Expression>(
+ findChild(syntax::NodeRole::CallExpression_callee));
+}
+
+syntax::Leaf *syntax::CallExpression::openParen() {
+ return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::OpenParen));
+}
+
+syntax::CallArguments *syntax::CallExpression::arguments() {
+ return cast_or_null<syntax::CallArguments>(
+ findChild(syntax::NodeRole::CallExpression_arguments));
+}
+
+syntax::Leaf *syntax::CallExpression::closeParen() {
+ return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::CloseParen));
+}
+
syntax::Leaf *syntax::SwitchStatement::switchKeyword() {
return cast_or_null<syntax::Leaf>(
findChild(syntax::NodeRole::IntroducerKeyword));
diff --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 398f12c45081..6ab01e8f65f0 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -316,12 +316,12 @@ TranslationUnit Detached
`-CompoundStatement
|-'{' OpenParen
|-ExpressionStatement CompoundStatement_statement
- | |-UnknownExpression ExpressionStatement_expression
- | | |-IdExpression
+ | |-CallExpression ExpressionStatement_expression
+ | | |-IdExpression CallExpression_callee
| | | `-UnqualifiedId IdExpression_id
| | | `-'test'
- | | |-'('
- | | `-')'
+ | | |-'(' OpenParen
+ | | `-')' CloseParen
| `-';'
|-IfStatement CompoundStatement_statement
| |-'if' IntroducerKeyword
@@ -330,21 +330,21 @@ TranslationUnit Detached
| | `-'1' LiteralToken
| |-')'
| |-ExpressionStatement IfStatement_thenStatement
- | | |-UnknownExpression ExpressionStatement_expression
- | | | |-IdExpression
+ | | |-CallExpression ExpressionStatement_expression
+ | | | |-IdExpression CallExpression_callee
| | | | `-UnqualifiedId IdExpression_id
| | | | `-'test'
- | | | |-'('
- | | | `-')'
+ | | | |-'(' OpenParen
+ | | | `-')' CloseParen
| | `-';'
| |-'else' IfStatement_elseKeyword
| `-ExpressionStatement IfStatement_elseStatement
- | |-UnknownExpression ExpressionStatement_expression
- | | |-IdExpression
+ | |-CallExpression ExpressionStatement_expression
+ | | |-IdExpression CallExpression_callee
| | | `-UnqualifiedId IdExpression_id
| | | `-'test'
- | | |-'('
- | | `-')'
+ | | |-'(' OpenParen
+ | | `-')' CloseParen
| `-';'
`-'}' CloseParen
)txt"));
@@ -378,20 +378,21 @@ void test(X x) {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-IdExpression
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
| `-UnqualifiedId IdExpression_id
| |-'operator'
| `-'+'
-|-'('
-|-IdExpression
-| `-UnqualifiedId IdExpression_id
-| `-'x'
-|-','
-|-IdExpression
-| `-UnqualifiedId IdExpression_id
-| `-'x'
-`-')'
+|-'(' OpenParen
+|-CallArguments CallExpression_arguments
+| |-IdExpression List_element
+| | `-UnqualifiedId IdExpression_id
+| | `-'x'
+| |-',' List_delimiter
+| `-IdExpression List_element
+| `-UnqualifiedId IdExpression_id
+| `-'x'
+`-')' CloseParen
)txt"}));
}
@@ -409,8 +410,8 @@ void test(X x) {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-MemberExpression
+CallExpression ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
| |-IdExpression MemberExpression_object
| | `-UnqualifiedId IdExpression_id
| | `-'x'
@@ -419,8 +420,8 @@ UnknownExpression ExpressionStatement_expression
| `-UnqualifiedId IdExpression_id
| |-'operator'
| `-'int'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt"}));
}
@@ -436,16 +437,17 @@ void test() {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-IdExpression
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
| `-UnqualifiedId IdExpression_id
| |-'operator'
| |-'""'
| `-'_w'
-|-'('
-|-CharacterLiteralExpression
-| `-''1'' LiteralToken
-`-')'
+|-'(' OpenParen
+|-CallArguments CallExpression_arguments
+| `-CharacterLiteralExpression List_element
+| `-''1'' LiteralToken
+`-')' CloseParen
)txt"}));
}
@@ -461,8 +463,8 @@ void test(X x) {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-MemberExpression
+CallExpression ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
| |-IdExpression MemberExpression_object
| | `-UnqualifiedId IdExpression_id
| | `-'x'
@@ -471,8 +473,8 @@ UnknownExpression ExpressionStatement_expression
| `-UnqualifiedId IdExpression_id
| |-'~'
| `-'X'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt"}));
}
@@ -492,8 +494,8 @@ void test(X x) {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-MemberExpression
+CallExpression ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
| |-IdExpression MemberExpression_object
| | `-UnqualifiedId IdExpression_id
| | `-'x'
@@ -506,7 +508,7 @@ UnknownExpression ExpressionStatement_expression
|-'x'
|-')'
|-'('
-`-')'
+`-')' CloseParen
)txt"}));
}
@@ -523,15 +525,15 @@ void test() {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-IdExpression
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
| `-UnqualifiedId IdExpression_id
| |-'f'
| |-'<'
| |-'int'
| `-'>'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt"}));
}
@@ -639,8 +641,8 @@ void test(S s) {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-IdExpression
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
| |-NestedNameSpecifier IdExpression_qualifier
| | |-DecltypeNameSpecifier List_element
| | | |-'decltype'
@@ -652,8 +654,8 @@ UnknownExpression ExpressionStatement_expression
| | `-'::' List_delimiter
| `-UnqualifiedId IdExpression_id
| `-'f'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt"}));
}
@@ -673,8 +675,8 @@ void test() {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-IdExpression
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
| |-NestedNameSpecifier IdExpression_qualifier
| | |-IdentifierNameSpecifier List_element
| | | `-'S'
@@ -684,12 +686,12 @@ UnknownExpression ExpressionStatement_expression
| |-'<'
| |-'int'
| `-'>'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt",
R"txt(
-UnknownExpression ExpressionStatement_expression
-|-IdExpression
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
| |-NestedNameSpecifier IdExpression_qualifier
| | |-IdentifierNameSpecifier List_element
| | | `-'S'
@@ -700,8 +702,8 @@ UnknownExpression ExpressionStatement_expression
| |-'<'
| |-'int'
| `-'>'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt"}));
}
@@ -723,8 +725,8 @@ void test() {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-IdExpression
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
| |-NestedNameSpecifier IdExpression_qualifier
| | |-'::' List_delimiter
| | |-IdentifierNameSpecifier List_element
@@ -743,8 +745,8 @@ UnknownExpression ExpressionStatement_expression
| |-'<'
| |-'int'
| `-'>'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt"}));
}
@@ -767,8 +769,8 @@ void test() {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-IdExpression
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
| |-NestedNameSpecifier IdExpression_qualifier
| | |-IdentifierNameSpecifier List_element
| | | `-'T'
@@ -782,12 +784,12 @@ UnknownExpression ExpressionStatement_expression
| | `-'::' List_delimiter
| `-UnqualifiedId IdExpression_id
| `-'f'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt",
R"txt(
-UnknownExpression ExpressionStatement_expression
-|-IdExpression
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
| |-NestedNameSpecifier IdExpression_qualifier
| | |-IdentifierNameSpecifier List_element
| | | `-'T'
@@ -797,12 +799,12 @@ UnknownExpression ExpressionStatement_expression
| | `-'::' List_delimiter
| `-UnqualifiedId IdExpression_id
| `-'f'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt",
R"txt(
-UnknownExpression ExpressionStatement_expression
-|-IdExpression
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
| |-NestedNameSpecifier IdExpression_qualifier
| | |-IdentifierNameSpecifier List_element
| | | `-'T'
@@ -814,8 +816,8 @@ UnknownExpression ExpressionStatement_expression
| |-IntegerLiteralExpression
| | `-'0' LiteralToken
| `-'>'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt"}));
}
@@ -2060,8 +2062,8 @@ void test(S s) {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-MemberExpression
+CallExpression ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
| |-IdExpression MemberExpression_object
| | `-UnqualifiedId IdExpression_id
| | `-'s'
@@ -2070,8 +2072,8 @@ UnknownExpression ExpressionStatement_expression
| `-UnqualifiedId IdExpression_id
| |-'operator'
| `-'!'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt"}));
}
@@ -2126,8 +2128,8 @@ void test(S* sp){
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-MemberExpression
+CallExpression ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
| |-IdExpression MemberExpression_object
| | `-UnqualifiedId IdExpression_id
| | `-'sp'
@@ -2138,8 +2140,8 @@ UnknownExpression ExpressionStatement_expression
| |-'<'
| |-'int'
| `-'>'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt"}));
}
@@ -2158,8 +2160,8 @@ void test(S s){
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-MemberExpression
+CallExpression ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
| |-IdExpression MemberExpression_object
| | `-UnqualifiedId IdExpression_id
| | `-'s'
@@ -2171,8 +2173,8 @@ UnknownExpression ExpressionStatement_expression
| |-'<'
| |-'int'
| `-'>'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt"}));
}
@@ -2192,8 +2194,8 @@ void test(S s){
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-MemberExpression
+CallExpression ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
| |-IdExpression MemberExpression_object
| | `-UnqualifiedId IdExpression_id
| | `-'s'
@@ -2205,12 +2207,12 @@ UnknownExpression ExpressionStatement_expression
| | `-'::' List_delimiter
| `-UnqualifiedId IdExpression_id
| `-'f'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt",
R"txt(
-UnknownExpression ExpressionStatement_expression
-|-MemberExpression
+CallExpression ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
| |-IdExpression MemberExpression_object
| | `-UnqualifiedId IdExpression_id
| | `-'s'
@@ -2224,8 +2226,8 @@ UnknownExpression ExpressionStatement_expression
| `-UnqualifiedId IdExpression_id
| |-'~'
| `-'S'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
)txt"}));
}
@@ -2253,10 +2255,10 @@ void test(S* sp) {
}
)cpp",
{R"txt(
-UnknownExpression ExpressionStatement_expression
-|-MemberExpression
-| |-UnknownExpression MemberExpression_object
-| | |-MemberExpression
+CallExpression ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
+| |-CallExpression MemberExpression_object
+| | |-MemberExpression CallExpression_callee
| | | |-IdExpression MemberExpression_object
| | | | `-UnqualifiedId IdExpression_id
| | | | `-'sp'
@@ -2264,8 +2266,8 @@ UnknownExpression ExpressionStatement_expression
| | | `-IdExpression MemberExpression_member
| | | `-UnqualifiedId IdExpression_id
| | | `-'getU'
-| | |-'('
-| | `-')'
+| | |-'(' OpenParen
+| | `-')' CloseParen
| |-'.' MemberExpression_accessToken
| `-IdExpression MemberExpression_member
| |-NestedNameSpecifier IdExpression_qualifier
@@ -2282,8 +2284,462 @@ UnknownExpression ExpressionStatement_expression
| |-'<'
| |-'int'
| `-'>'
-|-'('
-`-')'
+|-'(' OpenParen
+`-')' CloseParen
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, 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 ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
+| |-IdExpression MemberExpression_object
+| | `-UnqualifiedId IdExpression_id
+| | `-'s'
+| |-'.' MemberExpression_accessToken
+| `-IdExpression MemberExpression_member
+| `-UnqualifiedId IdExpression_id
+| `-'f'
+|-'(' OpenParen
+`-')' CloseParen
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, 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 ExpressionStatement_expression
+|-IdExpression CallExpression_callee
+| `-UnqualifiedId IdExpression_id
+| `-'s'
+|-'(' OpenParen
+`-')' CloseParen
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, 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 ExpressionStatement_expression
+|-CallExpression CallExpression_callee
+| |-IdExpression CallExpression_callee
+| | `-UnqualifiedId IdExpression_id
+| | `-'s'
+| |-'(' OpenParen
+| `-')' CloseParen
+|-'(' OpenParen
+`-')' CloseParen
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, 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 ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
+| |-ThisExpression MemberExpression_object
+| | `-'this' IntroducerKeyword
+| |-'->' MemberExpression_accessToken
+| `-IdExpression MemberExpression_member
+| `-UnqualifiedId IdExpression_id
+| `-'f'
+|-'(' OpenParen
+`-')' CloseParen
+ )txt",
+ R"txt(
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
+| `-UnqualifiedId IdExpression_id
+| `-'f'
+|-'(' OpenParen
+`-')' CloseParen
+ )txt",
+ R"txt(
+CallExpression ExpressionStatement_expression
+|-MemberExpression CallExpression_callee
+| |-ThisExpression MemberExpression_object
+| | `-'this' IntroducerKeyword
+| |-'->' MemberExpression_accessToken
+| `-IdExpression MemberExpression_member
+| |-NestedNameSpecifier IdExpression_qualifier
+| | |-IdentifierNameSpecifier List_element
+| | | `-'Base'
+| | `-'::' List_delimiter
+| `-UnqualifiedId IdExpression_id
+| `-'f'
+|-'(' OpenParen
+`-')' CloseParen
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, CallExpression_Callee_FunctionPointer) {
+ if (!GetParam().isCXX()) {
+ return;
+ }
+ EXPECT_TRUE(treeDumpEqualOnAnnotations(
+ R"cpp(
+void (*pf)();
+void test() {
+ [[pf()]];
+ [[(*pf)()]];
+}
+)cpp",
+ {R"txt(
+CallExpression ExpressionStatement_expression
+|-IdExpression CallExpression_callee
+| `-UnqualifiedId IdExpression_id
+| `-'pf'
+|-'(' OpenParen
+`-')' CloseParen
+)txt",
+ R"txt(
+CallExpression ExpressionStatement_expression
+|-ParenExpression CallExpression_callee
+| |-'(' OpenParen
+| |-PrefixUnaryOperatorExpression ParenExpression_subExpression
+| | |-'*' OperatorExpression_operatorToken
+| | `-IdExpression UnaryOperatorExpression_operand
+| | `-UnqualifiedId IdExpression_id
+| | `-'pf'
+| `-')' CloseParen
+|-'(' OpenParen
+`-')' CloseParen
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, 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 ExpressionStatement_expression
+|-ParenExpression CallExpression_callee
+| |-'(' OpenParen
+| |-BinaryOperatorExpression ParenExpression_subExpression
+| | |-IdExpression BinaryOperatorExpression_leftHandSide
+| | | `-UnqualifiedId IdExpression_id
+| | | `-'s'
+| | |-'.*' OperatorExpression_operatorToken
+| | `-IdExpression BinaryOperatorExpression_rightHandSide
+| | `-UnqualifiedId IdExpression_id
+| | `-'pmf'
+| `-')' CloseParen
+|-'(' OpenParen
+`-')' CloseParen
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, CallExpression_Arguments_Zero) {
+ if (!GetParam().isCXX()) {
+ return;
+ }
+ EXPECT_TRUE(treeDumpEqualOnAnnotations(
+ R"cpp(
+void f();
+void test() {
+ [[f();]]
+}
+)cpp",
+ {R"txt(
+ExpressionStatement CompoundStatement_statement
+|-CallExpression ExpressionStatement_expression
+| |-IdExpression CallExpression_callee
+| | `-UnqualifiedId IdExpression_id
+| | `-'f'
+| |-'(' OpenParen
+| `-')' CloseParen
+`-';'
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, CallExpression_Arguments_One) {
+ if (!GetParam().isCXX()) {
+ return;
+ }
+ EXPECT_TRUE(treeDumpEqualOnAnnotations(
+ R"cpp(
+void f(int);
+void test() {
+ [[f(1);]]
+}
+)cpp",
+ {R"txt(
+ExpressionStatement CompoundStatement_statement
+|-CallExpression ExpressionStatement_expression
+| |-IdExpression CallExpression_callee
+| | `-UnqualifiedId IdExpression_id
+| | `-'f'
+| |-'(' OpenParen
+| |-CallArguments CallExpression_arguments
+| | `-IntegerLiteralExpression List_element
+| | `-'1' LiteralToken
+| `-')' CloseParen
+`-';'
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, 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 CompoundStatement_statement
+|-CallExpression ExpressionStatement_expression
+| |-IdExpression CallExpression_callee
+| | `-UnqualifiedId IdExpression_id
+| | `-'f'
+| |-'(' OpenParen
+| |-CallArguments CallExpression_arguments
+| | |-IntegerLiteralExpression List_element
+| | | `-'1' LiteralToken
+| | |-',' List_delimiter
+| | |-CharacterLiteralExpression List_element
+| | | `-''2'' LiteralToken
+| | |-',' List_delimiter
+| | `-FloatingLiteralExpression List_element
+| | `-'3.' LiteralToken
+| `-')' CloseParen
+`-';'
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, 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 CompoundStatement_statement
+|-CallExpression ExpressionStatement_expression
+| |-IdExpression CallExpression_callee
+| | `-UnqualifiedId IdExpression_id
+| | `-'f'
+| |-'(' OpenParen
+| |-CallArguments CallExpression_arguments
+| | `-BinaryOperatorExpression List_element
+| | |-IdExpression BinaryOperatorExpression_leftHandSide
+| | | `-UnqualifiedId IdExpression_id
+| | | `-'a'
+| | |-'=' OperatorExpression_operatorToken
+| | `-IntegerLiteralExpression BinaryOperatorExpression_rightHandSide
+| | `-'1' LiteralToken
+| `-')' CloseParen
+`-';'
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, CallExpression_Arguments_BracedInitList_Empty) {
+ if (!GetParam().isCXX11OrLater()) {
+ return;
+ }
+ EXPECT_TRUE(treeDumpEqualOnAnnotations(
+ R"cpp(
+void f(int[]);
+void test() {
+ [[f({});]]
+}
+)cpp",
+ {R"txt(
+ExpressionStatement CompoundStatement_statement
+|-CallExpression ExpressionStatement_expression
+| |-IdExpression CallExpression_callee
+| | `-UnqualifiedId IdExpression_id
+| | `-'f'
+| |-'(' OpenParen
+| |-CallArguments CallExpression_arguments
+| | `-UnknownExpression List_element
+| | `-UnknownExpression
+| | |-'{'
+| | `-'}'
+| `-')' CloseParen
+`-';'
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, 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 CompoundStatement_statement
+|-CallExpression ExpressionStatement_expression
+| |-IdExpression CallExpression_callee
+| | `-UnqualifiedId IdExpression_id
+| | `-'f'
+| |-'(' OpenParen
+| |-CallArguments CallExpression_arguments
+| | `-UnknownExpression List_element
+| | `-UnknownExpression
+| | |-'{'
+| | |-IntegerLiteralExpression
+| | | `-'1' LiteralToken
+| | |-','
+| | |-UnknownExpression
+| | | `-UnknownExpression
+| | | |-'{'
+| | | `-'}'
+| | `-'}'
+| `-')' CloseParen
+`-';'
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, 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 CompoundStatement_statement
+|-CallExpression ExpressionStatement_expression
+| |-IdExpression CallExpression_callee
+| | `-UnqualifiedId IdExpression_id
+| | `-'f'
+| |-'(' OpenParen
+| |-CallArguments CallExpression_arguments
+| | `-UnknownExpression List_element
+| | `-UnknownExpression
+| | |-'{'
+| | |-UnknownExpression
+| | | |-'.'
+| | | |-'a'
+| | | |-'='
+| | | `-IntegerLiteralExpression
+| | | `-'1' LiteralToken
+| | |-','
+| | |-UnknownExpression
+| | | |-'.'
+| | | |-'b'
+| | | `-UnknownExpression
+| | | `-UnknownExpression
+| | | |-'{'
+| | | `-'}'
+| | `-'}'
+| `-')' CloseParen
+`-';'
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, 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 ExpressionStatement_expression
+|-UnknownExpression CallExpression_callee
+| `-'test'
+|-'(' OpenParen
+|-CallArguments CallExpression_arguments
+| `-UnknownExpression List_element
+| |-IdExpression
+| | `-UnqualifiedId IdExpression_id
+| | `-'args'
+| `-'...'
+`-')' CloseParen
)txt"}));
}
More information about the cfe-commits
mailing list