File: DisambiguateTest.cpp

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (111 lines) | stat: -rw-r--r-- 3,904 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//===--- DisambiguateTest.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang-pseudo/Disambiguate.h"
#include "clang-pseudo/Forest.h"
#include "clang-pseudo/Token.h"
#include "clang/Basic/TokenKinds.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <vector>

namespace clang {
namespace pseudo {
namespace {
using testing::ElementsAre;
using testing::Pair;
using testing::UnorderedElementsAre;

// Common disambiguation test fixture.
// This is the ambiguous forest representing parses of 'a * b;'.
class DisambiguateTest : public ::testing::Test {
protected:
  // Greatly simplified C++ grammar.
  enum Symbol : SymbolID {
    Statement,
    Declarator,
    Expression,
    DeclSpecifier,
    Type,
    Template,
  };
  enum Rule : RuleID {
    /* LHS__RHS1_RHS2 means LHS := RHS1 RHS2 */
    Statement__DeclSpecifier_Declarator_Semi,
    Declarator__Star_Declarator,
    Declarator__Identifier,
    Statement__Expression_Semi,
    Expression__Expression_Star_Expression,
    Expression__Identifier,
    DeclSpecifier__Type,
    DeclSpecifier__Template,
    Type__Identifier,
    Template__Identifier,
  };

  ForestArena Arena;
  ForestNode &A = Arena.createTerminal(tok::identifier, 0);
  ForestNode &Star = Arena.createTerminal(tok::star, 1);
  ForestNode &B = Arena.createTerminal(tok::identifier, 2);
  ForestNode &Semi = Arena.createTerminal(tok::semi, 3);

  // Parse as multiplication expression.
  ForestNode &AExpr =
      Arena.createSequence(Expression, Expression__Identifier, &A);
  ForestNode &BExpr =
      Arena.createSequence(Expression, Expression__Identifier, &B);
  ForestNode &Expr =
      Arena.createSequence(Expression, Expression__Expression_Star_Expression,
                           {&AExpr, &Star, &BExpr});
  ForestNode &ExprStmt = Arena.createSequence(
      Statement, Statement__Expression_Semi, {&Expr, &Semi});
  // Parse as declaration (`a` may be CTAD or not).
  ForestNode &AType =
      Arena.createSequence(DeclSpecifier, DeclSpecifier__Type,
                           &Arena.createSequence(Type, Type__Identifier, &A));
  ForestNode &ATemplate = Arena.createSequence(
      DeclSpecifier, DeclSpecifier__Template,
      &Arena.createSequence(Template, Template__Identifier, &A));
  ForestNode &DeclSpec =
      Arena.createAmbiguous(DeclSpecifier, {&AType, &ATemplate});
  ForestNode &BDeclarator =
      Arena.createSequence(Declarator, Declarator__Identifier, &B);
  ForestNode &BPtr = Arena.createSequence(
      Declarator, Declarator__Star_Declarator, {&Star, &BDeclarator});
  ForestNode &DeclStmt =
      Arena.createSequence(Statement, Statement__DeclSpecifier_Declarator_Semi,
                           {&DeclSpec, &Star, &BDeclarator});
  // Top-level ambiguity
  ForestNode &Stmt = Arena.createAmbiguous(Statement, {&ExprStmt, &DeclStmt});
};

TEST_F(DisambiguateTest, Remove) {
  Disambiguation D;
  D.try_emplace(&Stmt, 1);     // statement is a declaration, not an expression
  D.try_emplace(&DeclSpec, 0); // a is a type, not a (CTAD) template
  ForestNode *Root = &Stmt;
  removeAmbiguities(Root, D);

  EXPECT_EQ(Root, &DeclStmt);
  EXPECT_THAT(DeclStmt.elements(), ElementsAre(&AType, &Star, &BDeclarator));
}

TEST_F(DisambiguateTest, DummyStrategy) {
  Disambiguation D = disambiguate(&Stmt, {});
  EXPECT_THAT(D, UnorderedElementsAre(Pair(&Stmt, 1), Pair(&DeclSpec, 1)));

  ForestNode *Root = &Stmt;
  removeAmbiguities(Root, D);
  EXPECT_EQ(Root, &DeclStmt);
  EXPECT_THAT(DeclStmt.elements(),
              ElementsAre(&ATemplate, &Star, &BDeclarator));
}

} // namespace
} // namespace pseudo
} // namespace clang