1//===--- DisambiguateTest.cpp ---------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
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"
15#include <vector>
16
17namespace clang {
18namespace pseudo {
19namespace {
20using testing::ElementsAre;
21using testing::Pair;
22using testing::UnorderedElementsAre;
23
24// Common disambiguation test fixture.
25// This is the ambiguous forest representing parses of 'a * b;'.
26class DisambiguateTest : public ::testing::Test {
27protected:
28 // Greatly simplified C++ grammar.
29 enum Symbol : SymbolID {
30 Statement,
31 Declarator,
32 Expression,
33 DeclSpecifier,
34 Type,
35 Template,
36 };
37 enum Rule : RuleID {
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,
45 DeclSpecifier__Type,
46 DeclSpecifier__Template,
47 Type__Identifier,
48 Template__Identifier,
49 };
50
51 ForestArena Arena;
52 ForestNode &A = Arena.createTerminal(TK: tok::identifier, Start: 0);
53 ForestNode &Star = Arena.createTerminal(TK: tok::star, Start: 1);
54 ForestNode &B = Arena.createTerminal(TK: tok::identifier, Start: 2);
55 ForestNode &Semi = Arena.createTerminal(TK: tok::semi, Start: 3);
56
57 // Parse as multiplication expression.
58 ForestNode &AExpr =
59 Arena.createSequence(SID: Expression, RID: Expression__Identifier, Elements: &A);
60 ForestNode &BExpr =
61 Arena.createSequence(SID: Expression, RID: Expression__Identifier, Elements: &B);
62 ForestNode &Expr =
63 Arena.createSequence(SID: Expression, RID: Expression__Expression_Star_Expression,
64 Elements: {&AExpr, &Star, &BExpr});
65 ForestNode &ExprStmt = Arena.createSequence(
66 SID: Statement, RID: Statement__Expression_Semi, Elements: {&Expr, &Semi});
67 // Parse as declaration (`a` may be CTAD or not).
68 ForestNode &AType =
69 Arena.createSequence(SID: DeclSpecifier, RID: DeclSpecifier__Type,
70 Elements: &Arena.createSequence(SID: Type, RID: Type__Identifier, Elements: &A));
71 ForestNode &ATemplate = Arena.createSequence(
72 SID: DeclSpecifier, RID: DeclSpecifier__Template,
73 Elements: &Arena.createSequence(SID: Template, RID: Template__Identifier, Elements: &A));
74 ForestNode &DeclSpec =
75 Arena.createAmbiguous(SID: DeclSpecifier, Alternatives: {&AType, &ATemplate});
76 ForestNode &BDeclarator =
77 Arena.createSequence(SID: Declarator, RID: Declarator__Identifier, Elements: &B);
78 ForestNode &BPtr = Arena.createSequence(
79 SID: Declarator, RID: Declarator__Star_Declarator, Elements: {&Star, &BDeclarator});
80 ForestNode &DeclStmt =
81 Arena.createSequence(SID: Statement, RID: Statement__DeclSpecifier_Declarator_Semi,
82 Elements: {&DeclSpec, &Star, &BDeclarator});
83 // Top-level ambiguity
84 ForestNode &Stmt = Arena.createAmbiguous(SID: Statement, Alternatives: {&ExprStmt, &DeclStmt});
85};
86
87TEST_F(DisambiguateTest, Remove) {
88 Disambiguation D;
89 D.try_emplace(Key: &Stmt, Args: 1); // statement is a declaration, not an expression
90 D.try_emplace(Key: &DeclSpec, Args: 0); // a is a type, not a (CTAD) template
91 ForestNode *Root = &Stmt;
92 removeAmbiguities(Root, Disambig: D);
93
94 EXPECT_EQ(Root, &DeclStmt);
95 EXPECT_THAT(DeclStmt.elements(), ElementsAre(&AType, &Star, &BDeclarator));
96}
97
98TEST_F(DisambiguateTest, DummyStrategy) {
99 Disambiguation D = disambiguate(Root: &Stmt, Params: {});
100 EXPECT_THAT(D, UnorderedElementsAre(Pair(&Stmt, 1), Pair(&DeclSpec, 1)));
101
102 ForestNode *Root = &Stmt;
103 removeAmbiguities(Root, Disambig: D);
104 EXPECT_EQ(Root, &DeclStmt);
105 EXPECT_THAT(DeclStmt.elements(),
106 ElementsAre(&ATemplate, &Star, &BDeclarator));
107}
108
109} // namespace
110} // namespace pseudo
111} // namespace clang
112

source code of clang-tools-extra/pseudo/unittests/DisambiguateTest.cpp