diff --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp --- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp @@ -3855,8 +3855,76 @@ )txt")); } -TEST_P(BuildSyntaxTreeTest, NonModifiableNodes) { - // Some nodes are non-modifiable, they are marked with 'I:'. +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' + |-SimpleDeclarator Declarator + | |-'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' + |-SimpleDeclarator Declarator + | |-'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+ @@ -3896,21 +3964,16 @@ )txt")); } -TEST_P(BuildSyntaxTreeTest, ModifiableNodes) { - // All nodes can be mutated. +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 OPEN { -#define CLOSE } +#define MIN(X,Y) X < Y ? X : Y void test() { - OPEN - 1; - CLOSE - - OPEN - 2; - } + MIN(1,2); } )cpp", R"txt( @@ -3924,24 +3987,109 @@ | `-')' CloseParen `-CompoundStatement |-'{' OpenParen - |-CompoundStatement Statement - | |-'{' OpenParen - | |-ExpressionStatement Statement - | | |-IntegerLiteralExpression Expression + |-ExpressionStatement Statement + | |-UnknownExpression Expression + | | |-BinaryOperatorExpression unmodifiable + | | | |-IntegerLiteralExpression LeftHandSide + | | | | `-'1' LiteralToken + | | | |-'<' OperatorToken unmodifiable + | | | `-IntegerLiteralExpression RightHandSide + | | | `-'2' LiteralToken + | | |-'?' unmodifiable + | | |-IntegerLiteralExpression | | | `-'1' LiteralToken - | | `-';' - | `-'}' CloseParen - |-CompoundStatement Statement - | |-'{' OpenParen - | |-ExpressionStatement Statement - | | |-IntegerLiteralExpression Expression - | | | `-'2' LiteralToken - | | `-';' - | `-'}' CloseParen + | | |-':' 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' + |-SimpleDeclarator Declarator + | |-'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;