1 //===--- DisambiguateTest.cpp ---------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "clang-pseudo/Disambiguate.h"
10 #include "clang-pseudo/Forest.h"
11 #include "clang-pseudo/Token.h"
12 #include "clang/Basic/TokenKinds.h"
13 #include "gmock/gmock.h"
14 #include "gtest/gtest.h"
20 using testing::ElementsAre
;
22 using testing::UnorderedElementsAre
;
24 // Common disambiguation test fixture.
25 // This is the ambiguous forest representing parses of 'a * b;'.
26 class DisambiguateTest
: public ::testing::Test
{
28 // Greatly simplified C++ grammar.
29 enum Symbol
: SymbolID
{
38 /* LHS__RHS1_RHS2 means LHS := RHS1 RHS2 */
39 Statement__DeclSpecifier_Declarator_Semi
,
40 Declarator__Star_Declarator
,
41 Declarator__Identifier
,
42 Statement__Expression_Semi
,
43 Expression__Expression_Star_Expression
,
44 Expression__Identifier
,
46 DeclSpecifier__Template
,
52 ForestNode
&A
= Arena
.createTerminal(tok::identifier
, 0);
53 ForestNode
&Star
= Arena
.createTerminal(tok::star
, 1);
54 ForestNode
&B
= Arena
.createTerminal(tok::identifier
, 2);
55 ForestNode
&Semi
= Arena
.createTerminal(tok::semi
, 3);
57 // Parse as multiplication expression.
59 Arena
.createSequence(Expression
, Expression__Identifier
, &A
);
61 Arena
.createSequence(Expression
, Expression__Identifier
, &B
);
63 Arena
.createSequence(Expression
, Expression__Expression_Star_Expression
,
64 {&AExpr
, &Star
, &BExpr
});
65 ForestNode
&ExprStmt
= Arena
.createSequence(
66 Statement
, Statement__Expression_Semi
, {&Expr
, &Semi
});
67 // Parse as declaration (`a` may be CTAD or not).
69 Arena
.createSequence(DeclSpecifier
, DeclSpecifier__Type
,
70 &Arena
.createSequence(Type
, Type__Identifier
, &A
));
71 ForestNode
&ATemplate
= Arena
.createSequence(
72 DeclSpecifier
, DeclSpecifier__Template
,
73 &Arena
.createSequence(Template
, Template__Identifier
, &A
));
74 ForestNode
&DeclSpec
=
75 Arena
.createAmbiguous(DeclSpecifier
, {&AType
, &ATemplate
});
76 ForestNode
&BDeclarator
=
77 Arena
.createSequence(Declarator
, Declarator__Identifier
, &B
);
78 ForestNode
&BPtr
= Arena
.createSequence(
79 Declarator
, Declarator__Star_Declarator
, {&Star
, &BDeclarator
});
80 ForestNode
&DeclStmt
=
81 Arena
.createSequence(Statement
, Statement__DeclSpecifier_Declarator_Semi
,
82 {&DeclSpec
, &Star
, &BDeclarator
});
83 // Top-level ambiguity
84 ForestNode
&Stmt
= Arena
.createAmbiguous(Statement
, {&ExprStmt
, &DeclStmt
});
87 TEST_F(DisambiguateTest
, Remove
) {
89 D
.try_emplace(&Stmt
, 1); // statement is a declaration, not an expression
90 D
.try_emplace(&DeclSpec
, 0); // a is a type, not a (CTAD) template
91 ForestNode
*Root
= &Stmt
;
92 removeAmbiguities(Root
, D
);
94 EXPECT_EQ(Root
, &DeclStmt
);
95 EXPECT_THAT(DeclStmt
.elements(), ElementsAre(&AType
, &Star
, &BDeclarator
));
98 TEST_F(DisambiguateTest
, DummyStrategy
) {
99 Disambiguation D
= disambiguate(&Stmt
, {});
100 EXPECT_THAT(D
, UnorderedElementsAre(Pair(&Stmt
, 1), Pair(&DeclSpec
, 1)));
102 ForestNode
*Root
= &Stmt
;
103 removeAmbiguities(Root
, D
);
104 EXPECT_EQ(Root
, &DeclStmt
);
105 EXPECT_THAT(DeclStmt
.elements(),
106 ElementsAre(&ATemplate
, &Star
, &BDeclarator
));
110 } // namespace pseudo