IntegerLiteralExpression,
BoolLiteralExpression,
CharacterLiteralExpression,
+ StringLiteralExpression,
IdExpression,
// Statements.
syntax::Leaf *literalToken();
};
+/// Expression for string-literals. C++ [lex.string]
+class StringLiteralExpression final : public Expression {
+public:
+ StringLiteralExpression() : Expression(NodeKind::StringLiteralExpression) {}
+ static bool classof(const Node *N) {
+ return N->kind() == NodeKind::StringLiteralExpression;
+ }
+ syntax::Leaf *literalToken();
+};
+
/// An abstract class for prefix and postfix unary operators.
class UnaryOperatorExpression : public Expression {
public:
new (allocator()) syntax::CharacterLiteralExpression, S);
return true;
}
+ bool WalkUpFromStringLiteral(StringLiteral *S) {
+ Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken);
+ Builder.foldNode(Builder.getExprRange(S),
+ new (allocator()) syntax::StringLiteralExpression, S);
+ return true;
+ }
bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) {
Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
return OS << "BoolLiteralExpression";
case NodeKind::CharacterLiteralExpression:
return OS << "CharacterLiteralExpression";
+ case NodeKind::StringLiteralExpression:
+ return OS << "StringLiteralExpression";
case NodeKind::PrefixUnaryOperatorExpression:
return OS << "PrefixUnaryOperatorExpression";
case NodeKind::PostfixUnaryOperatorExpression:
findChild(syntax::NodeRole::LiteralToken));
}
+syntax::Leaf *syntax::StringLiteralExpression::literalToken() {
+ return llvm::cast_or_null<syntax::Leaf>(
+ findChild(syntax::NodeRole::LiteralToken));
+}
+
syntax::Leaf *syntax::CxxNullPtrExpression::nullPtrKeyword() {
return llvm::cast_or_null<syntax::Leaf>(
findChild(syntax::NodeRole::LiteralToken));
)txt"));
}
+TEST_P(SyntaxTreeTest, StringLiteral) {
+ EXPECT_TRUE(treeDumpEqual(
+ R"cpp(
+void test() {
+ "a\n\0\x20";
+ L"αβ";
+}
+)cpp",
+ R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+ |-void
+ |-SimpleDeclarator
+ | |-test
+ | `-ParametersAndQualifiers
+ | |-(
+ | `-)
+ `-CompoundStatement
+ |-{
+ |-ExpressionStatement
+ | |-StringLiteralExpression
+ | | `-"a\n\0\x20"
+ | `-;
+ |-ExpressionStatement
+ | |-StringLiteralExpression
+ | | `-L"αβ"
+ | `-;
+ `-}
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, StringLiteralUtf) {
+ if (!GetParam().isCXX11OrLater()) {
+ return;
+ }
+ EXPECT_TRUE(treeDumpEqual(
+ R"cpp(
+void test() {
+ u8"a\x1f\x05";
+ u"C++抽象構文木";
+ U"📖🌲\n";
+}
+)cpp",
+ R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+ |-void
+ |-SimpleDeclarator
+ | |-test
+ | `-ParametersAndQualifiers
+ | |-(
+ | `-)
+ `-CompoundStatement
+ |-{
+ |-ExpressionStatement
+ | |-StringLiteralExpression
+ | | `-u8"a\x1f\x05"
+ | `-;
+ |-ExpressionStatement
+ | |-StringLiteralExpression
+ | | `-u"C++抽象構文木"
+ | `-;
+ |-ExpressionStatement
+ | |-StringLiteralExpression
+ | | `-U"📖🌲\n"
+ | `-;
+ `-}
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, StringLiteralRaw) {
+ if (!GetParam().isCXX11OrLater()) {
+ return;
+ }
+ EXPECT_TRUE(treeDumpEqual(
+ R"cpp(
+void test() {
+ R"SyntaxTree(
+ Hello "Syntax" \"
+ )SyntaxTree";
+}
+)cpp",
+ R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+ |-void
+ |-SimpleDeclarator
+ | |-test
+ | `-ParametersAndQualifiers
+ | |-(
+ | `-)
+ `-CompoundStatement
+ |-{
+ |-ExpressionStatement
+ | |-StringLiteralExpression
+ | | `-R"SyntaxTree(
+ Hello "Syntax" \"
+ )SyntaxTree"
+ | `-;
+ `-}
+)txt"));
+}
+
TEST_P(SyntaxTreeTest, IntegerLiteral) {
EXPECT_TRUE(treeDumpEqual(
R"cpp(
| |-BoolLiteralExpression
| | `-true
| |-,
-| |-UnknownExpression
+| |-StringLiteralExpression
| | `-"message"
| |-)
| `-;