[clang] 461af57 - Add support for UnaryOperator in SyntaxTree
Dmitri Gribenko via cfe-commits
cfe-commits at lists.llvm.org
Wed May 27 08:23:18 PDT 2020
Author: Eduardo Caldas
Date: 2020-05-27T17:12:46+02:00
New Revision: 461af57de78155ee5d1dc1969b81dd019d228538
URL: https://github.com/llvm/llvm-project/commit/461af57de78155ee5d1dc1969b81dd019d228538
DIFF: https://github.com/llvm/llvm-project/commit/461af57de78155ee5d1dc1969b81dd019d228538.diff
LOG: Add support for UnaryOperator in SyntaxTree
Reviewers: gribozavr2
Reviewed By: gribozavr2
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D80624
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/TreeTest.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Tooling/Syntax/Nodes.h b/clang/include/clang/Tooling/Syntax/Nodes.h
index 5db99d4b9e35..e240becbf883 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -40,6 +40,8 @@ enum class NodeKind : uint16_t {
// Expressions.
UnknownExpression,
+ PrefixUnaryOperatorExpression,
+ PostfixUnaryOperatorExpression,
BinaryOperatorExpression,
// Statements.
@@ -105,6 +107,8 @@ enum class NodeRole : uint8_t {
BodyStatement,
// Roles specific to particular node kinds.
+ UnaryOperatorExpression_operatorToken,
+ UnaryOperatorExpression_operand,
BinaryOperatorExpression_leftHandSide,
BinaryOperatorExpression_operatorToken,
BinaryOperatorExpression_rightHandSide,
@@ -162,6 +166,50 @@ class UnknownExpression final : public Expression {
}
};
+/// An abstract class for prefix and postfix unary operators.
+class UnaryOperatorExpression : public Expression {
+public:
+ UnaryOperatorExpression(NodeKind K) : Expression(K) {}
+ static bool classof(const Node *N) {
+ return N->kind() == NodeKind::PrefixUnaryOperatorExpression ||
+ N->kind() == NodeKind::PostfixUnaryOperatorExpression;
+ }
+ syntax::Leaf *operatorToken();
+ syntax::Expression *operand();
+};
+
+/// <operator> <operand>
+///
+/// For example:
+/// +a -b
+/// !c not c
+/// ~d compl d
+/// *e &f
+/// ++h --h
+/// __real i __imag i
+class PrefixUnaryOperatorExpression final : public UnaryOperatorExpression {
+public:
+ PrefixUnaryOperatorExpression()
+ : UnaryOperatorExpression(NodeKind::PrefixUnaryOperatorExpression) {}
+ static bool classof(const Node *N) {
+ return N->kind() == NodeKind::PrefixUnaryOperatorExpression;
+ }
+};
+
+/// <operand> <operator>
+///
+/// For example:
+/// a++
+/// b--
+class PostfixUnaryOperatorExpression final : public UnaryOperatorExpression {
+public:
+ PostfixUnaryOperatorExpression()
+ : UnaryOperatorExpression(NodeKind::PostfixUnaryOperatorExpression) {}
+ static bool classof(const Node *N) {
+ return N->kind() == NodeKind::PostfixUnaryOperatorExpression;
+ }
+};
+
/// <lhs> <operator> <rhs>
///
/// For example:
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 8fee44cdbf10..60c6b3f88509 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -608,6 +608,25 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
return true;
}
+ bool WalkUpFromUnaryOperator(UnaryOperator *S) {
+ Builder.markChildToken(
+ S->getOperatorLoc(),
+ syntax::NodeRole::UnaryOperatorExpression_operatorToken);
+ Builder.markExprChild(S->getSubExpr(),
+ syntax::NodeRole::UnaryOperatorExpression_operand);
+
+ if (S->isPostfix())
+ Builder.foldNode(Builder.getExprRange(S),
+ new (allocator()) syntax::PostfixUnaryOperatorExpression,
+ S);
+ else
+ Builder.foldNode(Builder.getExprRange(S),
+ new (allocator()) syntax::PrefixUnaryOperatorExpression,
+ S);
+
+ return true;
+ }
+
bool WalkUpFromBinaryOperator(BinaryOperator *S) {
Builder.markExprChild(
S->getLHS(), syntax::NodeRole::BinaryOperatorExpression_leftHandSide);
diff --git a/clang/lib/Tooling/Syntax/Nodes.cpp b/clang/lib/Tooling/Syntax/Nodes.cpp
index 84c0143db81d..f0f1a8ed13c2 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -18,6 +18,10 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, NodeKind K) {
return OS << "TranslationUnit";
case NodeKind::UnknownExpression:
return OS << "UnknownExpression";
+ case NodeKind::PrefixUnaryOperatorExpression:
+ return OS << "PrefixUnaryOperatorExpression";
+ case NodeKind::PostfixUnaryOperatorExpression:
+ return OS << "PostfixUnaryOperatorExpression";
case NodeKind::BinaryOperatorExpression:
return OS << "BinaryOperatorExpression";
case NodeKind::UnknownStatement:
@@ -112,6 +116,10 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, NodeRole R) {
return OS << "IfStatement_elseKeyword";
case syntax::NodeRole::IfStatement_elseStatement:
return OS << "IfStatement_elseStatement";
+ case syntax::NodeRole::UnaryOperatorExpression_operatorToken:
+ return OS << "UnaryOperatorExpression_operatorToken";
+ case syntax::NodeRole::UnaryOperatorExpression_operand:
+ return OS << "UnaryOperatorExpression_operand";
case syntax::NodeRole::BinaryOperatorExpression_leftHandSide:
return OS << "BinaryOperatorExpression_leftHandSide";
case syntax::NodeRole::BinaryOperatorExpression_operatorToken:
@@ -155,6 +163,16 @@ syntax::Expression *syntax::BinaryOperatorExpression::lhs() {
findChild(syntax::NodeRole::BinaryOperatorExpression_leftHandSide));
}
+syntax::Leaf *syntax::UnaryOperatorExpression::operatorToken() {
+ return llvm::cast_or_null<syntax::Leaf>(
+ findChild(syntax::NodeRole::UnaryOperatorExpression_operatorToken));
+}
+
+syntax::Expression *syntax::UnaryOperatorExpression::operand() {
+ return llvm::cast_or_null<syntax::Expression>(
+ findChild(syntax::NodeRole::UnaryOperatorExpression_operand));
+}
+
syntax::Leaf *syntax::BinaryOperatorExpression::operatorToken() {
return llvm::cast_or_null<syntax::Leaf>(
findChild(syntax::NodeRole::BinaryOperatorExpression_operatorToken));
diff --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index 634f99f7c395..e81e3c2b8354 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -594,6 +594,161 @@ void test() {
)txt");
}
+TEST_F(SyntaxTreeTest, PostfixUnaryOperator) {
+ expectTreeDumpEqual(
+ R"cpp(
+void test(int a) {
+ a++;
+ a--;
+}
+ )cpp",
+ R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+ |-void
+ |-SimpleDeclarator
+ | |-test
+ | `-ParametersAndQualifiers
+ | |-(
+ | |-SimpleDeclaration
+ | | |-int
+ | | `-SimpleDeclarator
+ | | `-a
+ | `-)
+ `-CompoundStatement
+ |-{
+ |-ExpressionStatement
+ | |-PostfixUnaryOperatorExpression
+ | | |-UnknownExpression
+ | | | `-a
+ | | `-++
+ | `-;
+ |-ExpressionStatement
+ | |-PostfixUnaryOperatorExpression
+ | | |-UnknownExpression
+ | | | `-a
+ | | `---
+ | `-;
+ `-}
+)txt");
+}
+
+TEST_F(SyntaxTreeTest, PrefixUnaryOperator) {
+ expectTreeDumpEqual(
+ R"cpp(
+void test(int a, int *ap, bool b) {
+ --a; ++a;
+ ~a; compl a;
+ -a;
+ +a;
+ &a;
+ *ap;
+ !b; not b;
+ __real a; __imag a;
+}
+ )cpp",
+ R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+ |-void
+ |-SimpleDeclarator
+ | |-test
+ | `-ParametersAndQualifiers
+ | |-(
+ | |-SimpleDeclaration
+ | | |-int
+ | | `-SimpleDeclarator
+ | | `-a
+ | |-,
+ | |-SimpleDeclaration
+ | | |-int
+ | | `-SimpleDeclarator
+ | | |-*
+ | | `-ap
+ | |-,
+ | |-SimpleDeclaration
+ | | |-bool
+ | | `-SimpleDeclarator
+ | | `-b
+ | `-)
+ `-CompoundStatement
+ |-{
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |---
+ | | `-UnknownExpression
+ | | `-a
+ | `-;
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |-++
+ | | `-UnknownExpression
+ | | `-a
+ | `-;
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |-~
+ | | `-UnknownExpression
+ | | `-a
+ | `-;
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |-compl
+ | | `-UnknownExpression
+ | | `-a
+ | `-;
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |--
+ | | `-UnknownExpression
+ | | `-a
+ | `-;
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |-+
+ | | `-UnknownExpression
+ | | `-a
+ | `-;
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |-&
+ | | `-UnknownExpression
+ | | `-a
+ | `-;
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |-*
+ | | `-UnknownExpression
+ | | `-ap
+ | `-;
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |-!
+ | | `-UnknownExpression
+ | | `-b
+ | `-;
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |-not
+ | | `-UnknownExpression
+ | | `-b
+ | `-;
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |-__real
+ | | `-UnknownExpression
+ | | `-a
+ | `-;
+ |-ExpressionStatement
+ | |-PrefixUnaryOperatorExpression
+ | | |-__imag
+ | | `-UnknownExpression
+ | | `-a
+ | `-;
+ `-}
+)txt");
+}
+
TEST_F(SyntaxTreeTest, BinaryOperator) {
expectTreeDumpEqual(
R"cpp(
@@ -1866,7 +2021,7 @@ const int const *const *volatile b;
| |-SimpleDeclarator
| | |-west
| | |-=
-| | `-UnknownExpression
+| | `-PrefixUnaryOperatorExpression
| | |--
| | `-UnknownExpression
| | `-1
More information about the cfe-commits
mailing list