PrefixUnaryOperatorExpression,
PostfixUnaryOperatorExpression,
BinaryOperatorExpression,
+ ParenExpression,
IntegerLiteralExpression,
CharacterLiteralExpression,
FloatingLiteralExpression,
ParametersAndQualifiers_trailingReturn,
IdExpression_id,
IdExpression_qualifier,
- NestedNameSpecifier_specifier
+ NestedNameSpecifier_specifier,
+ ParenExpression_subExpression
};
/// For debugging purposes.
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeRole R);
}
};
+/// Models a parenthesized expression `(E)`. C++ [expr.prim.paren]
+/// e.g. `(3 + 2)` in `a = 1 + (3 + 2);`
+class ParenExpression final : public Expression {
+public:
+ ParenExpression() : Expression(NodeKind::ParenExpression) {}
+ static bool classof(const Node *N) {
+ return N->kind() == NodeKind::ParenExpression;
+ }
+ syntax::Leaf *openParen();
+ syntax::Expression *subExpression();
+ syntax::Leaf *closeParen();
+};
+
/// Expression for integer literals. C++ [lex.icon]
class IntegerLiteralExpression final : public Expression {
public:
return true;
}
+ bool WalkUpFromParenExpr(ParenExpr *S) {
+ Builder.markChildToken(S->getLParen(), syntax::NodeRole::OpenParen);
+ Builder.markExprChild(S->getSubExpr(),
+ syntax::NodeRole::ParenExpression_subExpression);
+ Builder.markChildToken(S->getRParen(), syntax::NodeRole::CloseParen);
+ Builder.foldNode(Builder.getExprRange(S),
+ new (allocator()) syntax::ParenExpression, S);
+ return true;
+ }
+
bool WalkUpFromIntegerLiteral(IntegerLiteral *S) {
Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
Builder.foldNode(Builder.getExprRange(S),
return OS << "TranslationUnit";
case NodeKind::UnknownExpression:
return OS << "UnknownExpression";
+ case NodeKind::ParenExpression:
+ return OS << "ParenExpression";
case NodeKind::IntegerLiteralExpression:
return OS << "IntegerLiteralExpression";
case NodeKind::CharacterLiteralExpression:
return OS << "IdExpression_qualifier";
case syntax::NodeRole::NestedNameSpecifier_specifier:
return OS << "NestedNameSpecifier_specifier";
+ case syntax::NodeRole::ParenExpression_subExpression:
+ return OS << "ParenExpression_subExpression";
}
llvm_unreachable("invalid role");
}
findChild(syntax::NodeRole::IdExpression_id));
}
+syntax::Leaf *syntax::ParenExpression::openParen() {
+ return llvm::cast_or_null<syntax::Leaf>(
+ findChild(syntax::NodeRole::OpenParen));
+}
+
+syntax::Expression *syntax::ParenExpression::subExpression() {
+ return llvm::cast_or_null<syntax::Expression>(
+ findChild(syntax::NodeRole::ParenExpression_subExpression));
+}
+
+syntax::Leaf *syntax::ParenExpression::closeParen() {
+ return llvm::cast_or_null<syntax::Leaf>(
+ findChild(syntax::NodeRole::CloseParen));
+}
+
syntax::Leaf *syntax::IntegerLiteralExpression::literalToken() {
return llvm::cast_or_null<syntax::Leaf>(
findChild(syntax::NodeRole::LiteralToken));
)txt"));
}
+TEST_P(SyntaxTreeTest, ParenExpr) {
+ EXPECT_TRUE(treeDumpEqual(
+ R"cpp(
+void test() {
+ (1);
+ ((1));
+ (1 + (2));
+}
+)cpp",
+ R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+ |-void
+ |-SimpleDeclarator
+ | |-test
+ | `-ParametersAndQualifiers
+ | |-(
+ | `-)
+ `-CompoundStatement
+ |-{
+ |-ExpressionStatement
+ | |-ParenExpression
+ | | |-(
+ | | |-IntegerLiteralExpression
+ | | | `-1
+ | | `-)
+ | `-;
+ |-ExpressionStatement
+ | |-ParenExpression
+ | | |-(
+ | | |-ParenExpression
+ | | | |-(
+ | | | |-IntegerLiteralExpression
+ | | | | `-1
+ | | | `-)
+ | | `-)
+ | `-;
+ |-ExpressionStatement
+ | |-ParenExpression
+ | | |-(
+ | | |-BinaryOperatorExpression
+ | | | |-IntegerLiteralExpression
+ | | | | `-1
+ | | | |-+
+ | | | `-ParenExpression
+ | | | |-(
+ | | | |-IntegerLiteralExpression
+ | | | | `-2
+ | | | `-)
+ | | `-)
+ | `-;
+ `-}
+)txt"));
+}
+
TEST_P(SyntaxTreeTest, IntegerLiteral) {
EXPECT_TRUE(treeDumpEqual(
R"cpp(
|-{
|-ExpressionStatement
| |-BinaryOperatorExpression
- | | |-UnknownExpression
+ | | |-ParenExpression
| | | |-(
| | | |-BinaryOperatorExpression
| | | | |-IntegerLiteralExpression
| | | | `-2
| | | `-)
| | |-*
- | | `-UnknownExpression
+ | | `-ParenExpression
| | |-(
| | |-BinaryOperatorExpression
| | | |-IntegerLiteralExpression