llvm-project

Форк
0
/
StructuralEquivalenceTest.cpp 
2652 строки · 87.7 Кб
1
#include "clang/AST/ASTContext.h"
2
#include "clang/AST/ASTStructuralEquivalence.h"
3
#include "clang/AST/Decl.h"
4
#include "clang/AST/DeclTemplate.h"
5
#include "clang/ASTMatchers/ASTMatchers.h"
6
#include "clang/Frontend/ASTUnit.h"
7
#include "clang/Testing/CommandLineArgs.h"
8
#include "clang/Tooling/Tooling.h"
9
#include "llvm/TargetParser/Host.h"
10

11
#include "DeclMatcher.h"
12

13
#include "gtest/gtest.h"
14

15
namespace clang {
16
namespace ast_matchers {
17

18
using std::get;
19

20
struct StructuralEquivalenceTest : ::testing::Test {
21
  std::unique_ptr<ASTUnit> AST0, AST1;
22
  std::string Code0, Code1; // Buffers for SourceManager
23

24
  // Parses the source code in the specified language and sets the ASTs of
25
  // the current test instance to the parse result.
26
  void makeASTUnits(const std::string &SrcCode0, const std::string &SrcCode1,
27
                    TestLanguage Lang) {
28
    this->Code0 = SrcCode0;
29
    this->Code1 = SrcCode1;
30
    std::vector<std::string> Args = getCommandLineArgsForTesting(Lang);
31

32
    const char *const InputFileName = "input.cc";
33

34
    AST0 = tooling::buildASTFromCodeWithArgs(Code0, Args, InputFileName);
35
    AST1 = tooling::buildASTFromCodeWithArgs(Code1, Args, InputFileName);
36
  }
37

38
  // Get a pair of node pointers into the synthesized AST from the given code
39
  // snippets. To determine the returned node, a separate matcher is specified
40
  // for both snippets. The first matching node is returned.
41
  template <typename NodeType, typename MatcherType>
42
  std::tuple<NodeType *, NodeType *>
43
  makeDecls(const std::string &SrcCode0, const std::string &SrcCode1,
44
            TestLanguage Lang, const MatcherType &Matcher0,
45
            const MatcherType &Matcher1) {
46
    makeASTUnits(SrcCode0, SrcCode1, Lang);
47

48
    NodeType *D0 = FirstDeclMatcher<NodeType>().match(
49
        AST0->getASTContext().getTranslationUnitDecl(), Matcher0);
50
    NodeType *D1 = FirstDeclMatcher<NodeType>().match(
51
        AST1->getASTContext().getTranslationUnitDecl(), Matcher1);
52

53
    return std::make_tuple(D0, D1);
54
  }
55

56
  std::tuple<TranslationUnitDecl *, TranslationUnitDecl *>
57
  makeTuDecls(const std::string &SrcCode0, const std::string &SrcCode1,
58
              TestLanguage Lang) {
59
    makeASTUnits(SrcCode0, SrcCode1, Lang);
60

61
    return std::make_tuple(AST0->getASTContext().getTranslationUnitDecl(),
62
                           AST1->getASTContext().getTranslationUnitDecl());
63
  }
64

65
  // Get a pair of node pointers into the synthesized AST from the given code
66
  // snippets. The same matcher is used for both snippets.
67
  template <typename NodeType, typename MatcherType>
68
  std::tuple<NodeType *, NodeType *>
69
  makeDecls(const std::string &SrcCode0, const std::string &SrcCode1,
70
            TestLanguage Lang, const MatcherType &AMatcher) {
71
    return makeDecls<NodeType, MatcherType>(
72
          SrcCode0, SrcCode1, Lang, AMatcher, AMatcher);
73
  }
74

75
  // Get a pair of Decl pointers to the synthesized declarations from the given
76
  // code snippets. We search for the first NamedDecl with given name in both
77
  // snippets.
78
  std::tuple<NamedDecl *, NamedDecl *>
79
  makeNamedDecls(const std::string &SrcCode0, const std::string &SrcCode1,
80
                 TestLanguage Lang, const char *const Identifier = "foo") {
81
    auto Matcher = namedDecl(hasName(Identifier));
82
    return makeDecls<NamedDecl>(SrcCode0, SrcCode1, Lang, Matcher);
83
  }
84

85
  // Wraps a Stmt and the ASTContext that contains it.
86
  struct StmtWithASTContext {
87
    Stmt *S;
88
    ASTContext *Context;
89
    explicit StmtWithASTContext(Stmt &S, ASTContext &Context)
90
        : S(&S), Context(&Context) {}
91
    explicit StmtWithASTContext(FunctionDecl *FD)
92
        : S(FD->getBody()), Context(&FD->getASTContext()) {}
93
  };
94

95
  // Get a pair of node pointers into the synthesized AST from the given code
96
  // snippets. To determine the returned node, a separate matcher is specified
97
  // for both snippets. The first matching node is returned.
98
  template <typename MatcherType>
99
  std::tuple<StmtWithASTContext, StmtWithASTContext>
100
  makeStmts(const std::string &SrcCode0, const std::string &SrcCode1,
101
            TestLanguage Lang, const MatcherType &Matcher0,
102
            const MatcherType &Matcher1) {
103
    makeASTUnits(SrcCode0, SrcCode1, Lang);
104

105
    Stmt *S0 = FirstDeclMatcher<Stmt>().match(
106
        AST0->getASTContext().getTranslationUnitDecl(), Matcher0);
107
    Stmt *S1 = FirstDeclMatcher<Stmt>().match(
108
        AST1->getASTContext().getTranslationUnitDecl(), Matcher1);
109

110
    return std::make_tuple(StmtWithASTContext(*S0, AST0->getASTContext()),
111
                           StmtWithASTContext(*S1, AST1->getASTContext()));
112
  }
113

114
  // Get a pair of node pointers into the synthesized AST from the given code
115
  // snippets. The same matcher is used for both snippets.
116
  template <typename MatcherType>
117
  std::tuple<StmtWithASTContext, StmtWithASTContext>
118
  makeStmts(const std::string &SrcCode0, const std::string &SrcCode1,
119
            TestLanguage Lang, const MatcherType &AMatcher) {
120
    return makeStmts(SrcCode0, SrcCode1, Lang, AMatcher, AMatcher);
121
  }
122

123
  // Convenience function for makeStmts that wraps the code inside a function
124
  // body.
125
  template <typename MatcherType>
126
  std::tuple<StmtWithASTContext, StmtWithASTContext>
127
  makeWrappedStmts(const std::string &SrcCode0, const std::string &SrcCode1,
128
                   TestLanguage Lang, const MatcherType &AMatcher) {
129
    auto Wrap = [](const std::string &Src) {
130
      return "void wrapped() {" + Src + ";}";
131
    };
132
    return makeStmts(Wrap(SrcCode0), Wrap(SrcCode1), Lang, AMatcher);
133
  }
134

135
  bool testStructuralMatch(Decl *D0, Decl *D1,
136
                           bool IgnoreTemplateParmDepth = false) {
137
    llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls01;
138
    llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls10;
139
    StructuralEquivalenceContext Ctx01(
140
        D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls01,
141
        StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false,
142
        /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
143
        IgnoreTemplateParmDepth);
144
    StructuralEquivalenceContext Ctx10(
145
        D1->getASTContext(), D0->getASTContext(), NonEquivalentDecls10,
146
        StructuralEquivalenceKind::Default, /*StrictTypeSpelling=*/false,
147
        /*Complain=*/false, /*ErrorOnTagTypeMismatch=*/false,
148
        IgnoreTemplateParmDepth);
149
    bool Eq01 = Ctx01.IsEquivalent(D0, D1);
150
    bool Eq10 = Ctx10.IsEquivalent(D1, D0);
151
    EXPECT_EQ(Eq01, Eq10);
152
    return Eq01;
153
  }
154

155
  bool testStructuralMatch(StmtWithASTContext S0, StmtWithASTContext S1) {
156
    llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls01;
157
    llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls10;
158
    StructuralEquivalenceContext Ctx01(
159
        *S0.Context, *S1.Context, NonEquivalentDecls01,
160
        StructuralEquivalenceKind::Default, false, false);
161
    StructuralEquivalenceContext Ctx10(
162
        *S1.Context, *S0.Context, NonEquivalentDecls10,
163
        StructuralEquivalenceKind::Default, false, false);
164
    bool Eq01 = Ctx01.IsEquivalent(S0.S, S1.S);
165
    bool Eq10 = Ctx10.IsEquivalent(S1.S, S0.S);
166
    EXPECT_EQ(Eq01, Eq10);
167
    return Eq01;
168
  }
169

170
  bool
171
  testStructuralMatch(std::tuple<StmtWithASTContext, StmtWithASTContext> t) {
172
    return testStructuralMatch(get<0>(t), get<1>(t));
173
  }
174

175
  bool testStructuralMatch(std::tuple<Decl *, Decl *> t,
176
                           bool IgnoreTemplateParmDepth = false) {
177
    return testStructuralMatch(get<0>(t), get<1>(t), IgnoreTemplateParmDepth);
178
  }
179
};
180

181
TEST_F(StructuralEquivalenceTest, Int) {
182
  auto Decls = makeNamedDecls("int foo;", "int foo;", Lang_CXX03);
183
  EXPECT_TRUE(testStructuralMatch(Decls));
184
}
185

186
TEST_F(StructuralEquivalenceTest, IntVsSignedInt) {
187
  auto Decls = makeNamedDecls("int foo;", "signed int foo;", Lang_CXX03);
188
  EXPECT_TRUE(testStructuralMatch(Decls));
189
}
190

191
TEST_F(StructuralEquivalenceTest, Char) {
192
  auto Decls = makeNamedDecls("char foo;", "char foo;", Lang_CXX03);
193
  EXPECT_TRUE(testStructuralMatch(Decls));
194
}
195

196
// This test is disabled for now.
197
// FIXME Whether this is equivalent is dependent on the target.
198
TEST_F(StructuralEquivalenceTest, DISABLED_CharVsSignedChar) {
199
  auto Decls = makeNamedDecls("char foo;", "signed char foo;", Lang_CXX03);
200
  EXPECT_FALSE(testStructuralMatch(Decls));
201
}
202

203
TEST_F(StructuralEquivalenceTest, ForwardRecordDecl) {
204
  auto Decls = makeNamedDecls("struct foo;", "struct foo;", Lang_CXX03);
205
  EXPECT_TRUE(testStructuralMatch(Decls));
206
}
207

208
TEST_F(StructuralEquivalenceTest, IntVsSignedIntInStruct) {
209
  auto Decls = makeNamedDecls("struct foo { int x; };",
210
                              "struct foo { signed int x; };", Lang_CXX03);
211
  EXPECT_TRUE(testStructuralMatch(Decls));
212
}
213

214
TEST_F(StructuralEquivalenceTest, CharVsSignedCharInStruct) {
215
  auto Decls = makeNamedDecls("struct foo { char x; };",
216
                              "struct foo { signed char x; };", Lang_CXX03);
217
  EXPECT_FALSE(testStructuralMatch(Decls));
218
}
219

220
TEST_F(StructuralEquivalenceTest, IntVsSignedIntTemplateSpec) {
221
  auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
222
      R"(template <class T> struct foo; template<> struct foo<int>{};)",
223
      R"(template <class T> struct foo; template<> struct foo<signed int>{};)",
224
      Lang_CXX03, classTemplateSpecializationDecl());
225
  auto Spec0 = get<0>(Decls);
226
  auto Spec1 = get<1>(Decls);
227
  EXPECT_TRUE(testStructuralMatch(Spec0, Spec1));
228
}
229

230
TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpec) {
231
  auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
232
      R"(template <class T> struct foo; template<> struct foo<char>{};)",
233
      R"(template <class T> struct foo; template<> struct foo<signed char>{};)",
234
      Lang_CXX03, classTemplateSpecializationDecl());
235
  auto Spec0 = get<0>(Decls);
236
  auto Spec1 = get<1>(Decls);
237
  EXPECT_FALSE(testStructuralMatch(Spec0, Spec1));
238
}
239

240
TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpecWithInheritance) {
241
  auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
242
      R"(
243
      struct true_type{};
244
      template <class T> struct foo;
245
      template<> struct foo<char> : true_type {};
246
      )",
247
      R"(
248
      struct true_type{};
249
      template <class T> struct foo;
250
      template<> struct foo<signed char> : true_type {};
251
      )",
252
      Lang_CXX03, classTemplateSpecializationDecl());
253
  EXPECT_FALSE(testStructuralMatch(Decls));
254
}
255

256
// This test is disabled for now.
257
// FIXME Enable it, once the check is implemented.
258
TEST_F(StructuralEquivalenceTest, DISABLED_WrongOrderInNamespace) {
259
  auto Code =
260
      R"(
261
      namespace NS {
262
      template <class T> class Base {
263
          int a;
264
      };
265
      class Derived : Base<Derived> {
266
      };
267
      }
268
      void foo(NS::Derived &);
269
      )";
270
  auto Decls = makeNamedDecls(Code, Code, Lang_CXX03);
271

272
  NamespaceDecl *NS =
273
      LastDeclMatcher<NamespaceDecl>().match(get<1>(Decls), namespaceDecl());
274
  ClassTemplateDecl *TD = LastDeclMatcher<ClassTemplateDecl>().match(
275
      get<1>(Decls), classTemplateDecl(hasName("Base")));
276

277
  // Reorder the decls, move the TD to the last place in the DC.
278
  NS->removeDecl(TD);
279
  NS->addDeclInternal(TD);
280

281
  EXPECT_FALSE(testStructuralMatch(Decls));
282
}
283

284
TEST_F(StructuralEquivalenceTest, WrongOrderOfFieldsInClass) {
285
  auto Code = "class X { int a; int b; };";
286
  auto Decls = makeNamedDecls(Code, Code, Lang_CXX03, "X");
287

288
  CXXRecordDecl *RD = FirstDeclMatcher<CXXRecordDecl>().match(
289
      get<1>(Decls), cxxRecordDecl(hasName("X")));
290
  FieldDecl *FD =
291
      FirstDeclMatcher<FieldDecl>().match(get<1>(Decls), fieldDecl(hasName("a")));
292

293
  // Reorder the FieldDecls
294
  RD->removeDecl(FD);
295
  RD->addDeclInternal(FD);
296

297
  EXPECT_FALSE(testStructuralMatch(Decls));
298
}
299

300
struct StructuralEquivalenceFunctionTest : StructuralEquivalenceTest {
301
};
302

303
TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) {
304
  auto t = makeNamedDecls("void foo();", "template<class T> void foo();",
305
                          Lang_CXX03);
306
  EXPECT_FALSE(testStructuralMatch(t));
307
}
308

309
TEST_F(StructuralEquivalenceFunctionTest, DifferentOperators) {
310
  auto t = makeDecls<FunctionDecl>(
311
      "struct X{}; bool operator<(X, X);", "struct X{}; bool operator==(X, X);",
312
      Lang_CXX03, functionDecl(hasOverloadedOperatorName("<")),
313
      functionDecl(hasOverloadedOperatorName("==")));
314
  EXPECT_FALSE(testStructuralMatch(t));
315
}
316

317
TEST_F(StructuralEquivalenceFunctionTest, SameOperators) {
318
  auto t = makeDecls<FunctionDecl>(
319
      "struct X{}; bool operator<(X, X);", "struct X{}; bool operator<(X, X);",
320
      Lang_CXX03, functionDecl(hasOverloadedOperatorName("<")),
321
      functionDecl(hasOverloadedOperatorName("<")));
322
  EXPECT_TRUE(testStructuralMatch(t));
323
}
324

325
TEST_F(StructuralEquivalenceFunctionTest, CtorVsDtor) {
326
  auto t = makeDecls<FunctionDecl>("struct X{ X(); };", "struct X{ ~X(); };",
327
                                   Lang_CXX03, cxxConstructorDecl(),
328
                                   cxxDestructorDecl());
329
  EXPECT_FALSE(testStructuralMatch(t));
330
}
331

332
TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) {
333
  auto t =
334
      makeNamedDecls("void foo(int&);", "void foo(const int&);", Lang_CXX03);
335
  EXPECT_FALSE(testStructuralMatch(t));
336
}
337

338
TEST_F(StructuralEquivalenceFunctionTest, ParamConstSimple) {
339
  auto t = makeNamedDecls("void foo(int);", "void foo(const int);", Lang_CXX03);
340
  EXPECT_TRUE(testStructuralMatch(t));
341
  // consider this OK
342
}
343

344
TEST_F(StructuralEquivalenceFunctionTest, Throw) {
345
  auto t = makeNamedDecls("void foo();", "void foo() throw();", Lang_CXX03);
346
  EXPECT_FALSE(testStructuralMatch(t));
347
}
348

349
TEST_F(StructuralEquivalenceFunctionTest, Noexcept) {
350
  auto t = makeNamedDecls("void foo();",
351
                          "void foo() noexcept;", Lang_CXX11);
352
  EXPECT_FALSE(testStructuralMatch(t));
353
}
354

355
TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexcept) {
356
  auto t = makeNamedDecls("void foo() throw();",
357
                          "void foo() noexcept;", Lang_CXX11);
358
  EXPECT_FALSE(testStructuralMatch(t));
359
}
360

361
TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptFalse) {
362
  auto t = makeNamedDecls("void foo() throw();",
363
                          "void foo() noexcept(false);", Lang_CXX11);
364
  EXPECT_FALSE(testStructuralMatch(t));
365
}
366

367
TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptTrue) {
368
  auto t = makeNamedDecls("void foo() throw();",
369
                          "void foo() noexcept(true);", Lang_CXX11);
370
  EXPECT_FALSE(testStructuralMatch(t));
371
}
372

373
TEST_F(StructuralEquivalenceFunctionTest, NoexceptNonMatch) {
374
  auto t = makeNamedDecls("void foo() noexcept(false);",
375
                          "void foo() noexcept(true);", Lang_CXX11);
376
  EXPECT_FALSE(testStructuralMatch(t));
377
}
378

379
TEST_F(StructuralEquivalenceFunctionTest, NoexceptMatch) {
380
  auto t = makeNamedDecls("void foo() noexcept(false);",
381
                          "void foo() noexcept(false);", Lang_CXX11);
382
  EXPECT_TRUE(testStructuralMatch(t));
383
}
384

385
TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptFalse) {
386
  auto t = makeNamedDecls("void foo() noexcept;",
387
                          "void foo() noexcept(false);", Lang_CXX11);
388
  EXPECT_FALSE(testStructuralMatch(t));
389
}
390

391
TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptTrue) {
392
  auto t = makeNamedDecls("void foo() noexcept;",
393
                          "void foo() noexcept(true);", Lang_CXX11);
394
  EXPECT_FALSE(testStructuralMatch(t));
395
}
396

397
TEST_F(StructuralEquivalenceFunctionTest, ReturnType) {
398
  auto t = makeNamedDecls("char foo();", "int foo();", Lang_CXX03);
399
  EXPECT_FALSE(testStructuralMatch(t));
400
}
401

402
TEST_F(StructuralEquivalenceFunctionTest, ReturnConst) {
403
  auto t = makeNamedDecls("char foo();", "const char foo();", Lang_CXX03);
404
  EXPECT_FALSE(testStructuralMatch(t));
405
}
406

407
TEST_F(StructuralEquivalenceFunctionTest, ReturnRef) {
408
  auto t = makeNamedDecls("char &foo();",
409
                          "char &&foo();", Lang_CXX11);
410
  EXPECT_FALSE(testStructuralMatch(t));
411
}
412

413
TEST_F(StructuralEquivalenceFunctionTest, ParamCount) {
414
  auto t = makeNamedDecls("void foo(int);", "void foo(int, int);", Lang_CXX03);
415
  EXPECT_FALSE(testStructuralMatch(t));
416
}
417

418
TEST_F(StructuralEquivalenceFunctionTest, ParamType) {
419
  auto t = makeNamedDecls("void foo(int);", "void foo(char);", Lang_CXX03);
420
  EXPECT_FALSE(testStructuralMatch(t));
421
}
422

423
TEST_F(StructuralEquivalenceFunctionTest, ParamName) {
424
  auto t = makeNamedDecls("void foo(int a);", "void foo(int b);", Lang_CXX03);
425
  EXPECT_TRUE(testStructuralMatch(t));
426
}
427

428
TEST_F(StructuralEquivalenceFunctionTest, Variadic) {
429
  auto t =
430
      makeNamedDecls("void foo(int x...);", "void foo(int x);", Lang_CXX03);
431
  EXPECT_FALSE(testStructuralMatch(t));
432
}
433

434
TEST_F(StructuralEquivalenceFunctionTest, ParamPtr) {
435
  auto t = makeNamedDecls("void foo(int *);", "void foo(int);", Lang_CXX03);
436
  EXPECT_FALSE(testStructuralMatch(t));
437
}
438

439
TEST_F(StructuralEquivalenceFunctionTest, NameInParen) {
440
  auto t = makeNamedDecls("void ((foo))();", "void foo();", Lang_CXX03);
441
  EXPECT_TRUE(testStructuralMatch(t));
442
}
443

444
TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithExceptionSpec) {
445
  auto t = makeNamedDecls(
446
      "void (foo)() throw(int);",
447
      "void (foo)() noexcept;",
448
      Lang_CXX11);
449
  EXPECT_FALSE(testStructuralMatch(t));
450
}
451

452
TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithConst) {
453
  auto t = makeNamedDecls(
454
      "struct A { void (foo)() const; };",
455
      "struct A { void (foo)(); };",
456
      Lang_CXX11);
457
  EXPECT_FALSE(testStructuralMatch(t));
458
}
459

460
TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentNoreturnAttr) {
461
  auto t = makeNamedDecls("__attribute__((noreturn)) void foo();",
462
                          "                          void foo();", Lang_C99);
463
  EXPECT_TRUE(testStructuralMatch(t));
464
}
465

466
TEST_F(StructuralEquivalenceFunctionTest,
467
    FunctionsWithDifferentCallingConventions) {
468
  // These attributes may not be available on certain platforms.
469
  if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
470
      llvm::Triple::x86_64)
471
    GTEST_SKIP();
472
  auto t = makeNamedDecls("__attribute__((preserve_all)) void foo();",
473
                          "__attribute__((ms_abi))   void foo();", Lang_C99);
474
  EXPECT_FALSE(testStructuralMatch(t));
475
}
476

477
TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) {
478
  if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
479
      llvm::Triple::x86_64)
480
    GTEST_SKIP();
481
  auto t = makeNamedDecls(
482
      "__attribute__((no_caller_saved_registers)) void foo();",
483
      "                                           void foo();", Lang_C99);
484
  EXPECT_FALSE(testStructuralMatch(t));
485
}
486

487
struct StructuralEquivalenceCXXMethodTest : StructuralEquivalenceTest {
488
};
489

490
TEST_F(StructuralEquivalenceCXXMethodTest, Virtual) {
491
  auto t = makeDecls<CXXMethodDecl>("struct X { void foo(); };",
492
                                    "struct X { virtual void foo(); };",
493
                                    Lang_CXX03, cxxMethodDecl(hasName("foo")));
494
  EXPECT_FALSE(testStructuralMatch(t));
495
}
496

497
TEST_F(StructuralEquivalenceCXXMethodTest, Pure) {
498
  auto t = makeNamedDecls("struct X { virtual void foo(); };",
499
                          "struct X { virtual void foo() = 0; };", Lang_CXX03);
500
  EXPECT_FALSE(testStructuralMatch(t));
501
}
502

503
TEST_F(StructuralEquivalenceCXXMethodTest, DISABLED_Final) {
504
  // The final-ness is not checked yet.
505
  auto t =
506
      makeNamedDecls("struct X { virtual void foo(); };",
507
                     "struct X { virtual void foo() final; };", Lang_CXX03);
508
  EXPECT_FALSE(testStructuralMatch(t));
509
}
510

511
TEST_F(StructuralEquivalenceCXXMethodTest, Const) {
512
  auto t = makeNamedDecls("struct X { void foo(); };",
513
                          "struct X { void foo() const; };", Lang_CXX03);
514
  EXPECT_FALSE(testStructuralMatch(t));
515
}
516

517
TEST_F(StructuralEquivalenceCXXMethodTest, Static) {
518
  auto t = makeNamedDecls("struct X { void foo(); };",
519
                          "struct X { static void foo(); };", Lang_CXX03);
520
  EXPECT_FALSE(testStructuralMatch(t));
521
}
522

523
TEST_F(StructuralEquivalenceCXXMethodTest, Ref1) {
524
  auto t = makeNamedDecls("struct X { void foo(); };",
525
                          "struct X { void foo() &&; };", Lang_CXX11);
526
  EXPECT_FALSE(testStructuralMatch(t));
527
}
528

529
TEST_F(StructuralEquivalenceCXXMethodTest, Ref2) {
530
  auto t = makeNamedDecls("struct X { void foo() &; };",
531
                          "struct X { void foo() &&; };", Lang_CXX11);
532
  EXPECT_FALSE(testStructuralMatch(t));
533
}
534

535
TEST_F(StructuralEquivalenceCXXMethodTest, AccessSpecifier) {
536
  auto t = makeDecls<CXXMethodDecl>("struct X { public: void foo(); };",
537
                                    "struct X { private: void foo(); };",
538
                                    Lang_CXX03, cxxMethodDecl(hasName("foo")));
539
  EXPECT_FALSE(testStructuralMatch(t));
540
}
541

542
TEST_F(StructuralEquivalenceCXXMethodTest, Delete) {
543
  auto t = makeNamedDecls("struct X { void foo(); };",
544
                          "struct X { void foo() = delete; };", Lang_CXX11);
545
  EXPECT_FALSE(testStructuralMatch(t));
546
}
547

548
TEST_F(StructuralEquivalenceCXXMethodTest, Constructor) {
549
  auto t = makeDecls<FunctionDecl>("void foo();", "struct foo { foo(); };",
550
                                   Lang_CXX03, functionDecl(hasName("foo")),
551
                                   cxxConstructorDecl(hasName("foo")));
552
  EXPECT_FALSE(testStructuralMatch(t));
553
}
554

555
TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorParam) {
556
  auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
557
                                         "struct X { X(int); };", Lang_CXX03,
558
                                         cxxConstructorDecl(hasName("X")));
559
  EXPECT_FALSE(testStructuralMatch(t));
560
}
561

562
TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorExplicit) {
563
  auto t = makeDecls<CXXConstructorDecl>("struct X { X(int); };",
564
                                         "struct X { explicit X(int); };",
565
                                         Lang_CXX11,
566
                                         cxxConstructorDecl(hasName("X")));
567
  EXPECT_FALSE(testStructuralMatch(t));
568
}
569

570
TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorDefault) {
571
  auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
572
                                         "struct X { X() = default; };",
573
                                         Lang_CXX11,
574
                                         cxxConstructorDecl(hasName("X")));
575
  EXPECT_FALSE(testStructuralMatch(t));
576
}
577

578
TEST_F(StructuralEquivalenceCXXMethodTest, Conversion) {
579
  auto t = makeDecls<CXXConversionDecl>("struct X { operator bool(); };",
580
                                        "struct X { operator char(); };",
581
                                         Lang_CXX11,
582
                                         cxxConversionDecl());
583
  EXPECT_FALSE(testStructuralMatch(t));
584
}
585

586
TEST_F(StructuralEquivalenceCXXMethodTest, Operator) {
587
  auto t =
588
      makeDecls<FunctionDecl>("struct X { int operator +(int); };",
589
                              "struct X { int operator -(int); };", Lang_CXX03,
590
                              functionDecl(hasOverloadedOperatorName("+")),
591
                              functionDecl(hasOverloadedOperatorName("-")));
592
  EXPECT_FALSE(testStructuralMatch(t));
593
}
594

595
TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass1) {
596
  auto t = makeDecls<FunctionDecl>(
597
      "struct X { virtual void f(); }; void X::f() { }",
598
      "struct X { virtual void f() { }; };", Lang_CXX03,
599
      functionDecl(allOf(hasName("f"), isDefinition())));
600
  EXPECT_TRUE(testStructuralMatch(t));
601
}
602

603
TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass2) {
604
  auto t = makeDecls<FunctionDecl>(
605
      "struct X { virtual void f(); }; void X::f() { }",
606
      "struct X { void f(); }; void X::f() { }", Lang_CXX03,
607
      functionDecl(allOf(hasName("f"), isDefinition())));
608
  EXPECT_FALSE(testStructuralMatch(t));
609
}
610

611
struct StructuralEquivalenceRecordTest : StructuralEquivalenceTest {
612
  // FIXME Use a common getRecordDecl with ASTImporterTest.cpp!
613
  RecordDecl *getRecordDecl(FieldDecl *FD) {
614
    auto *ET = cast<ElaboratedType>(FD->getType().getTypePtr());
615
    return cast<RecordType>(ET->getNamedType().getTypePtr())->getDecl();
616
  };
617
};
618

619
TEST_F(StructuralEquivalenceRecordTest, Name) {
620
  auto t = makeDecls<CXXRecordDecl>("struct A{ };", "struct B{ };", Lang_CXX03,
621
                                    cxxRecordDecl(hasName("A")),
622
                                    cxxRecordDecl(hasName("B")));
623
  EXPECT_FALSE(testStructuralMatch(t));
624
}
625

626
TEST_F(StructuralEquivalenceRecordTest, Fields) {
627
  auto t = makeNamedDecls("struct foo{ int x; };", "struct foo{ char x; };",
628
                          Lang_CXX03);
629
  EXPECT_FALSE(testStructuralMatch(t));
630
}
631

632
TEST_F(StructuralEquivalenceRecordTest, DISABLED_Methods) {
633
  // Currently, methods of a class are not checked at class equivalence.
634
  auto t = makeNamedDecls("struct foo{ int x(); };", "struct foo{ char x(); };",
635
                          Lang_CXX03);
636
  EXPECT_FALSE(testStructuralMatch(t));
637
}
638

639
TEST_F(StructuralEquivalenceRecordTest, Bases) {
640
  auto t = makeNamedDecls("struct A{ }; struct foo: A { };",
641
                          "struct B{ }; struct foo: B { };", Lang_CXX03);
642
  EXPECT_FALSE(testStructuralMatch(t));
643
}
644

645
TEST_F(StructuralEquivalenceRecordTest, InheritanceVirtual) {
646
  auto t =
647
      makeNamedDecls("struct A{ }; struct foo: A { };",
648
                     "struct A{ }; struct foo: virtual A { };", Lang_CXX03);
649
  EXPECT_FALSE(testStructuralMatch(t));
650
}
651

652
TEST_F(StructuralEquivalenceRecordTest, DISABLED_InheritanceType) {
653
  // Access specifier in inheritance is not checked yet.
654
  auto t =
655
      makeNamedDecls("struct A{ }; struct foo: public A { };",
656
                     "struct A{ }; struct foo: private A { };", Lang_CXX03);
657
  EXPECT_FALSE(testStructuralMatch(t));
658
}
659

660
TEST_F(StructuralEquivalenceRecordTest, Match) {
661
  auto Code = R"(
662
      struct A{ };
663
      struct B{ };
664
      struct foo: A, virtual B {
665
        void x();
666
        int a;
667
      };
668
      )";
669
  auto t = makeNamedDecls(Code, Code, Lang_CXX03);
670
  EXPECT_TRUE(testStructuralMatch(t));
671
}
672

673
TEST_F(StructuralEquivalenceRecordTest, UnnamedRecordsShouldBeInequivalent) {
674
  auto t = makeTuDecls(
675
      R"(
676
      struct A {
677
        struct {
678
          struct A *next;
679
        } entry0;
680
        struct {
681
          struct A *next;
682
        } entry1;
683
      };
684
      )",
685
      "", Lang_C99);
686
  auto *TU = get<0>(t);
687
  auto *Entry0 =
688
      FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry0")));
689
  auto *Entry1 =
690
      FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry1")));
691
  auto *R0 = getRecordDecl(Entry0);
692
  auto *R1 = getRecordDecl(Entry1);
693

694
  ASSERT_NE(R0, R1);
695
  EXPECT_TRUE(testStructuralMatch(R0, R0));
696
  EXPECT_TRUE(testStructuralMatch(R1, R1));
697
  EXPECT_FALSE(testStructuralMatch(R0, R1));
698
}
699

700
TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) {
701
  auto t = makeTuDecls(
702
      R"(
703
      struct X {
704
        struct {
705
          int a;
706
        };
707
        struct {
708
          int b;
709
        };
710
      };
711
      )",
712
      "", Lang_C99);
713
  auto *TU = get<0>(t);
714
  auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
715
      TU, indirectFieldDecl(hasName("a")));
716
  auto *FA = cast<FieldDecl>(A->chain().front());
717
  RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
718
  auto *B = FirstDeclMatcher<IndirectFieldDecl>().match(
719
      TU, indirectFieldDecl(hasName("b")));
720
  auto *FB = cast<FieldDecl>(B->chain().front());
721
  RecordDecl *RB = cast<RecordType>(FB->getType().getTypePtr())->getDecl();
722

723
  ASSERT_NE(RA, RB);
724
  EXPECT_TRUE(testStructuralMatch(RA, RA));
725
  EXPECT_TRUE(testStructuralMatch(RB, RB));
726
  EXPECT_FALSE(testStructuralMatch(RA, RB));
727
}
728

729
TEST_F(StructuralEquivalenceRecordTest,
730
       RecordsAreInequivalentIfOrderOfAnonRecordsIsDifferent) {
731
  auto t = makeTuDecls(
732
      R"(
733
      struct X {
734
        struct { int a; };
735
        struct { int b; };
736
      };
737
      )",
738
      R"(
739
      struct X { // The order is reversed.
740
        struct { int b; };
741
        struct { int a; };
742
      };
743
      )",
744
      Lang_C99);
745

746
  auto *TU = get<0>(t);
747
  auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
748
      TU, indirectFieldDecl(hasName("a")));
749
  auto *FA = cast<FieldDecl>(A->chain().front());
750
  RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
751

752
  auto *TU1 = get<1>(t);
753
  auto *A1 = FirstDeclMatcher<IndirectFieldDecl>().match(
754
      TU1, indirectFieldDecl(hasName("a")));
755
  auto *FA1 = cast<FieldDecl>(A1->chain().front());
756
  RecordDecl *RA1 = cast<RecordType>(FA1->getType().getTypePtr())->getDecl();
757

758
  RecordDecl *X =
759
      FirstDeclMatcher<RecordDecl>().match(TU, recordDecl(hasName("X")));
760
  RecordDecl *X1 =
761
      FirstDeclMatcher<RecordDecl>().match(TU1, recordDecl(hasName("X")));
762
  ASSERT_NE(X, X1);
763
  EXPECT_FALSE(testStructuralMatch(X, X1));
764

765
  ASSERT_NE(RA, RA1);
766
  EXPECT_TRUE(testStructuralMatch(RA, RA));
767
  EXPECT_TRUE(testStructuralMatch(RA1, RA1));
768
  EXPECT_FALSE(testStructuralMatch(RA1, RA));
769
}
770

771
TEST_F(StructuralEquivalenceRecordTest,
772
       UnnamedRecordsShouldBeInequivalentEvenIfTheSecondIsBeingDefined) {
773
  auto Code =
774
      R"(
775
      struct A {
776
        struct {
777
          struct A *next;
778
        } entry0;
779
        struct {
780
          struct A *next;
781
        } entry1;
782
      };
783
      )";
784
  auto t = makeTuDecls(Code, Code, Lang_C99);
785

786
  auto *FromTU = get<0>(t);
787
  auto *Entry1 =
788
      FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("entry1")));
789

790
  auto *ToTU = get<1>(t);
791
  auto *Entry0 =
792
      FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0")));
793
  auto *A =
794
      FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
795
  A->startDefinition(); // Set isBeingDefined, getDefinition() will return a
796
                        // nullptr. This may be the case during ASTImport.
797

798
  auto *R0 = getRecordDecl(Entry0);
799
  auto *R1 = getRecordDecl(Entry1);
800

801
  ASSERT_NE(R0, R1);
802
  EXPECT_TRUE(testStructuralMatch(R0, R0));
803
  EXPECT_TRUE(testStructuralMatch(R1, R1));
804
  EXPECT_FALSE(testStructuralMatch(R0, R1));
805
}
806

807
TEST_F(StructuralEquivalenceRecordTest, TemplateVsNonTemplate) {
808
  auto t = makeDecls<CXXRecordDecl>("struct A { };",
809
                                    "template<class T> struct A { };",
810
                                    Lang_CXX03, cxxRecordDecl(hasName("A")));
811
  EXPECT_FALSE(testStructuralMatch(t));
812
}
813

814
TEST_F(StructuralEquivalenceRecordTest,
815
    FwdDeclRecordShouldBeEqualWithFwdDeclRecord) {
816
  auto t = makeNamedDecls("class foo;", "class foo;", Lang_CXX11);
817
  EXPECT_TRUE(testStructuralMatch(t));
818
}
819

820
TEST_F(StructuralEquivalenceRecordTest,
821
       FwdDeclRecordShouldBeEqualWithRecordWhichHasDefinition) {
822
  auto t =
823
      makeNamedDecls("class foo;", "class foo { int A; };", Lang_CXX11);
824
  EXPECT_TRUE(testStructuralMatch(t));
825
}
826

827
TEST_F(StructuralEquivalenceRecordTest,
828
       RecordShouldBeEqualWithRecordWhichHasDefinition) {
829
  auto t = makeNamedDecls("class foo { int A; };", "class foo { int A; };",
830
                          Lang_CXX11);
831
  EXPECT_TRUE(testStructuralMatch(t));
832
}
833

834
TEST_F(StructuralEquivalenceRecordTest, RecordsWithDifferentBody) {
835
  auto t = makeNamedDecls("class foo { int B; };", "class foo { int A; };",
836
                          Lang_CXX11);
837
  EXPECT_FALSE(testStructuralMatch(t));
838
}
839

840
TEST_F(StructuralEquivalenceRecordTest, SameFriendMultipleTimes) {
841
  auto t = makeNamedDecls("struct foo { friend class X; };",
842
                          "struct foo { friend class X; friend class X; };",
843
                          Lang_CXX11);
844
  EXPECT_FALSE(testStructuralMatch(t));
845
}
846

847
TEST_F(StructuralEquivalenceRecordTest, SameFriendsDifferentOrder) {
848
  auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };",
849
                          "struct foo { friend class Y; friend class X; };",
850
                          Lang_CXX11);
851
  EXPECT_FALSE(testStructuralMatch(t));
852
}
853

854
TEST_F(StructuralEquivalenceRecordTest, SameFriendsSameOrder) {
855
  auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };",
856
                          "struct foo { friend class X; friend class Y; };",
857
                          Lang_CXX11);
858
  EXPECT_TRUE(testStructuralMatch(t));
859
}
860

861
struct StructuralEquivalenceLambdaTest : StructuralEquivalenceTest {};
862

863
TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentMethods) {
864
  // Get the LambdaExprs, unfortunately we can't match directly the underlying
865
  // implicit CXXRecordDecl of the Lambda classes.
866
  auto t = makeDecls<LambdaExpr>(
867
      "void f() { auto L0 = [](int){}; }",
868
      "void f() { auto L1 = [](){}; }",
869
      Lang_CXX11,
870
      lambdaExpr(),
871
      lambdaExpr());
872
  CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
873
  CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
874
  EXPECT_FALSE(testStructuralMatch(L0, L1));
875
}
876

877
TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqMethods) {
878
  auto t = makeDecls<LambdaExpr>(
879
      "void f() { auto L0 = [](int){}; }",
880
      "void f() { auto L1 = [](int){}; }",
881
      Lang_CXX11,
882
      lambdaExpr(),
883
      lambdaExpr());
884
  CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
885
  CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
886
  EXPECT_TRUE(testStructuralMatch(L0, L1));
887
}
888

889
TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentFields) {
890
  auto t = makeDecls<LambdaExpr>(
891
      "void f() { char* X; auto L0 = [X](){}; }",
892
      "void f() { float X; auto L1 = [X](){}; }",
893
      Lang_CXX11,
894
      lambdaExpr(),
895
      lambdaExpr());
896
  CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
897
  CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
898
  EXPECT_FALSE(testStructuralMatch(L0, L1));
899
}
900

901
TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqFields) {
902
  auto t = makeDecls<LambdaExpr>(
903
      "void f() { float X; auto L0 = [X](){}; }",
904
      "void f() { float X; auto L1 = [X](){}; }",
905
      Lang_CXX11,
906
      lambdaExpr(),
907
      lambdaExpr());
908
  CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
909
  CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
910
  EXPECT_TRUE(testStructuralMatch(L0, L1));
911
}
912

913
TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) {
914
  auto t = makeNamedDecls("struct A{ }; struct B{ }; void foo(A a, A b);",
915
                          "struct A{ }; struct B{ }; void foo(A a, B b);",
916
                          Lang_CXX03);
917
  EXPECT_FALSE(testStructuralMatch(t));
918
}
919

920
TEST_F(StructuralEquivalenceTest, ExplicitBoolDifferent) {
921
  auto Decls = makeNamedDecls("struct foo {explicit(false) foo(int);};",
922
                              "struct foo {explicit(true) foo(int);};", Lang_CXX20);
923
  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
924
      get<0>(Decls), cxxConstructorDecl(hasName("foo")));
925
  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
926
      get<1>(Decls), cxxConstructorDecl(hasName("foo")));
927
  EXPECT_FALSE(testStructuralMatch(First, Second));
928
}
929

930
TEST_F(StructuralEquivalenceTest, ExplicitBoolSame) {
931
  auto Decls = makeNamedDecls("struct foo {explicit(true) foo(int);};",
932
                              "struct foo {explicit(true) foo(int);};", Lang_CXX20);
933
  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
934
      get<0>(Decls), cxxConstructorDecl(hasName("foo")));
935
  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
936
      get<1>(Decls), cxxConstructorDecl(hasName("foo")));
937
  EXPECT_TRUE(testStructuralMatch(First, Second));
938
}
939

940
struct StructuralEquivalenceRecordContextTest : StructuralEquivalenceTest {};
941

942
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsNamed) {
943
  auto Decls =
944
      makeNamedDecls("class X;", "namespace N { class X; }", Lang_CXX03, "X");
945
  EXPECT_FALSE(testStructuralMatch(Decls));
946
}
947

948
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNamedVsNamed) {
949
  auto Decls = makeNamedDecls("namespace A { class X; }",
950
                              "namespace B { class X; }", Lang_CXX03, "X");
951
  EXPECT_FALSE(testStructuralMatch(Decls));
952
}
953

954
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsNamed) {
955
  auto Decls = makeNamedDecls("namespace { class X; }",
956
                              "namespace N { class X; }", Lang_CXX03, "X");
957
  EXPECT_FALSE(testStructuralMatch(Decls));
958
}
959

960
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsAnon) {
961
  auto Decls =
962
      makeNamedDecls("class X;", "namespace { class X; }", Lang_CXX03, "X");
963
  EXPECT_FALSE(testStructuralMatch(Decls));
964
}
965

966
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnon) {
967
  auto Decls = makeNamedDecls("namespace { class X; }",
968
                              "namespace { class X; }", Lang_CXX03, "X");
969
  EXPECT_TRUE(testStructuralMatch(Decls));
970
}
971

972
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnonAnon) {
973
  auto Decls =
974
      makeNamedDecls("namespace { class X; }",
975
                     "namespace { namespace { class X; } }", Lang_CXX03, "X");
976
  EXPECT_FALSE(testStructuralMatch(Decls));
977
}
978

979
TEST_F(StructuralEquivalenceRecordContextTest,
980
       NamespaceNamedNamedVsNamedNamed) {
981
  auto Decls = makeNamedDecls("namespace A { namespace N { class X; } }",
982
                              "namespace B { namespace N { class X; } }",
983
                              Lang_CXX03, "X");
984
  EXPECT_FALSE(testStructuralMatch(Decls));
985
}
986

987
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNamedVsInline) {
988
  auto Decls = makeNamedDecls("namespace A { namespace A { class X; } }",
989
                              "namespace A { inline namespace A { class X; } }",
990
                              Lang_CXX17, "X");
991
  EXPECT_FALSE(testStructuralMatch(Decls));
992
}
993

994
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineVsInline) {
995
  auto Decls = makeNamedDecls("namespace A { inline namespace A { class X; } }",
996
                              "namespace A { inline namespace B { class X; } }",
997
                              Lang_CXX17, "X");
998
  EXPECT_TRUE(testStructuralMatch(Decls));
999
}
1000

1001
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineTopLevel) {
1002
  auto Decls =
1003
      makeNamedDecls("inline namespace A { class X; }",
1004
                     "inline namespace B { class X; }", Lang_CXX17, "X");
1005
  EXPECT_TRUE(testStructuralMatch(Decls));
1006
}
1007

1008
TEST_F(StructuralEquivalenceRecordContextTest, TransparentContext) {
1009
  auto Decls =
1010
      makeNamedDecls("extern \"C\" { class X; }", "class X;", Lang_CXX03, "X");
1011
  EXPECT_TRUE(testStructuralMatch(Decls));
1012
}
1013

1014
TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextNE) {
1015
  auto Decls = makeNamedDecls("extern \"C\" { class X; }",
1016
                              "namespace { class X; }", Lang_CXX03, "X");
1017
  EXPECT_FALSE(testStructuralMatch(Decls));
1018
}
1019

1020
TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextInNamespace) {
1021
  auto Decls = makeNamedDecls("extern \"C\" { namespace N { class X; } }",
1022
                              "namespace N { extern \"C\" { class X; } }",
1023
                              Lang_CXX03, "X");
1024
  EXPECT_TRUE(testStructuralMatch(Decls));
1025
}
1026

1027
TEST_F(StructuralEquivalenceRecordContextTest,
1028
       ClassTemplateSpecializationContext) {
1029
  std::string Code =
1030
      R"(
1031
      template <typename T> struct O {
1032
        struct M {};
1033
      };
1034
      )";
1035
  auto t = makeDecls<VarDecl>(Code + R"(
1036
      typedef O<int>::M MT1;
1037
      MT1 A;
1038
      )",
1039
                              Code + R"(
1040
      namespace {
1041
        struct I {};
1042
      } // namespace
1043
      typedef O<I>::M MT2;
1044
      MT2 A;
1045
      )",
1046
                              Lang_CXX11, varDecl(hasName("A")));
1047
  EXPECT_FALSE(testStructuralMatch(t));
1048
}
1049

1050
TEST_F(StructuralEquivalenceTest, NamespaceOfRecordMember) {
1051
  auto Decls = makeNamedDecls(
1052
      R"(
1053
      class X;
1054
      class Y { X* x; };
1055
      )",
1056
      R"(
1057
      namespace N { class X; }
1058
      class Y { N::X* x; };
1059
      )",
1060
      Lang_CXX03, "Y");
1061
  EXPECT_FALSE(testStructuralMatch(Decls));
1062
}
1063

1064
TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototype) {
1065
  auto Decls =
1066
      makeNamedDecls("struct Param { int a; }; void foo(struct Param *p);",
1067
                     "void foo(struct Param { int a; } *p);", Lang_C89);
1068
  EXPECT_TRUE(testStructuralMatch(Decls));
1069
}
1070

1071
TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototypeDifferentName) {
1072
  auto Decls =
1073
      makeNamedDecls("struct Param1 { int a; }; void foo(struct Param1 *p);",
1074
                     "void foo(struct Param2 { int a; } *p);", Lang_C89);
1075
  EXPECT_FALSE(testStructuralMatch(Decls));
1076
}
1077

1078
TEST_F(StructuralEquivalenceRecordContextTest, RecordInsideFunction) {
1079
  auto Decls = makeNamedDecls("struct Param { int a; };",
1080
                              "void f() { struct Param { int a; }; }", Lang_C89,
1081
                              "Param");
1082
  EXPECT_TRUE(testStructuralMatch(Decls));
1083
}
1084

1085
struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
1086

1087
TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) {
1088
  auto t = makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11);
1089
  EXPECT_TRUE(testStructuralMatch(t));
1090
}
1091

1092
TEST_F(StructuralEquivalenceEnumTest,
1093
       FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition) {
1094
  auto t =
1095
      makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11);
1096
  EXPECT_TRUE(testStructuralMatch(t));
1097
}
1098

1099
TEST_F(StructuralEquivalenceEnumTest,
1100
       EnumShouldBeEqualWithEnumWhichHasDefinition) {
1101
  auto t = makeNamedDecls("enum class foo { A };", "enum class foo { A };",
1102
                          Lang_CXX11);
1103
  EXPECT_TRUE(testStructuralMatch(t));
1104
}
1105

1106
TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) {
1107
  auto t = makeNamedDecls("enum class foo { B };", "enum class foo { A };",
1108
                          Lang_CXX11);
1109
  EXPECT_FALSE(testStructuralMatch(t));
1110
}
1111

1112
struct StructuralEquivalenceEnumConstantTest : StructuralEquivalenceTest {};
1113

1114
TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithSameValues) {
1115
  auto t = makeNamedDecls("enum foo { foo = 1 };", "enum foo { foo = 1 };",
1116
                          Lang_C89);
1117
  EXPECT_TRUE(testStructuralMatch(t));
1118
}
1119

1120
TEST_F(StructuralEquivalenceEnumConstantTest,
1121
       EnumConstantsWithDifferentValues) {
1122
  auto t =
1123
      makeNamedDecls("enum e { foo = 1 };", "enum e { foo = 2 };", Lang_C89);
1124
  EXPECT_FALSE(testStructuralMatch(t));
1125
}
1126

1127
TEST_F(StructuralEquivalenceEnumConstantTest,
1128
       EnumConstantsWithDifferentExprsButSameValues) {
1129
  auto t = makeNamedDecls("enum e { foo = 1 + 1 };", "enum e { foo = 2 };",
1130
                          Lang_CXX11);
1131
  EXPECT_FALSE(testStructuralMatch(t));
1132
}
1133

1134
TEST_F(StructuralEquivalenceEnumConstantTest,
1135
       EnumConstantsWithDifferentSignedness) {
1136
  auto t = makeNamedDecls("enum e : unsigned { foo = 1 };",
1137
                          "enum e : int { foo = 1 };", Lang_CXX11);
1138
  EXPECT_FALSE(testStructuralMatch(t));
1139
}
1140

1141
TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentWidth) {
1142
  auto t = makeNamedDecls("enum e : short { foo = 1 };",
1143
                          "enum e : int { foo = 1 };", Lang_CXX11);
1144
  EXPECT_FALSE(testStructuralMatch(t));
1145
}
1146

1147
TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithDifferentName) {
1148
  auto t =
1149
      makeDecls<EnumConstantDecl>("enum e { foo = 1 };", "enum e { bar = 1 };",
1150
                                  Lang_CXX11, enumConstantDecl());
1151
  EXPECT_FALSE(testStructuralMatch(t));
1152
}
1153

1154
struct StructuralEquivalenceObjCCategoryTest : StructuralEquivalenceTest {};
1155

1156
TEST_F(StructuralEquivalenceObjCCategoryTest, MatchinCategoryNames) {
1157
  auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1158
                                       "@interface A @end @interface A(X) @end",
1159
                                       Lang_OBJC, objcCategoryDecl());
1160
  EXPECT_TRUE(testStructuralMatch(t));
1161
}
1162

1163
TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesForDifferentClasses) {
1164
  auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1165
                                       "@interface B @end @interface B(X) @end",
1166
                                       Lang_OBJC, objcCategoryDecl());
1167
  EXPECT_FALSE(testStructuralMatch(t));
1168
}
1169

1170
TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithDifferentNames) {
1171
  auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1172
                                       "@interface A @end @interface A(Y) @end",
1173
                                       Lang_OBJC, objcCategoryDecl());
1174
  EXPECT_FALSE(testStructuralMatch(t));
1175
}
1176

1177
TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithoutInterfaces) {
1178
  auto t = makeDecls<ObjCCategoryDecl>("                  @interface A(X) @end",
1179
                                       "@interface A @end @interface A(X) @end",
1180
                                       Lang_OBJC, objcCategoryDecl());
1181
  EXPECT_FALSE(testStructuralMatch(t));
1182

1183
  auto t2 = makeDecls<ObjCCategoryDecl>("@interface A(X) @end",
1184
                                        "@interface A(X) @end",
1185
                                        Lang_OBJC, objcCategoryDecl());
1186
  EXPECT_TRUE(testStructuralMatch(t2));
1187
}
1188

1189
TEST_F(StructuralEquivalenceObjCCategoryTest, CategoryAndExtension) {
1190
  auto t = makeDecls<ObjCCategoryDecl>("@interface A @end @interface A(X) @end",
1191
                                       "@interface A @end @interface A() @end",
1192
                                       Lang_OBJC, objcCategoryDecl());
1193
  EXPECT_FALSE(testStructuralMatch(t));
1194
}
1195

1196
TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingProtocols) {
1197
  auto t = makeDecls<ObjCCategoryDecl>(
1198
      "@protocol P @end @interface A @end @interface A(X)<P> @end",
1199
      "@protocol P @end @interface A @end @interface A(X)<P> @end", Lang_OBJC,
1200
      objcCategoryDecl());
1201
  EXPECT_TRUE(testStructuralMatch(t));
1202
}
1203

1204
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocols) {
1205
  auto t = makeDecls<ObjCCategoryDecl>(
1206
      "@protocol P @end @interface A @end @interface A(X)<P> @end",
1207
      "@protocol Q @end @interface A @end @interface A(X)<Q> @end", Lang_OBJC,
1208
      objcCategoryDecl());
1209
  EXPECT_FALSE(testStructuralMatch(t));
1210
}
1211

1212
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentProtocolsOrder) {
1213
  auto t = makeDecls<ObjCCategoryDecl>(
1214
      "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<P, "
1215
      "Q> @end",
1216
      "@protocol P @end @protocol Q @end @interface A @end @interface A(X)<Q, "
1217
      "P> @end",
1218
      Lang_OBJC, objcCategoryDecl());
1219
  EXPECT_FALSE(testStructuralMatch(t));
1220
}
1221

1222
TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingIvars) {
1223
  auto t = makeDecls<ObjCCategoryDecl>(
1224
      "@interface A @end @interface A() { int x; } @end",
1225
      "@interface A @end @interface A() { int x; } @end", Lang_OBJC,
1226
      objcCategoryDecl());
1227
  EXPECT_TRUE(testStructuralMatch(t));
1228
}
1229

1230
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarName) {
1231
  auto t = makeDecls<ObjCCategoryDecl>(
1232
      "@interface A @end @interface A() { int x; } @end",
1233
      "@interface A @end @interface A() { int y; } @end", Lang_OBJC,
1234
      objcCategoryDecl());
1235
  EXPECT_FALSE(testStructuralMatch(t));
1236
}
1237

1238
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarType) {
1239
  auto t = makeDecls<ObjCCategoryDecl>(
1240
      "@interface A @end @interface A() { int x; } @end",
1241
      "@interface A @end @interface A() { float x; } @end", Lang_OBJC,
1242
      objcCategoryDecl());
1243
  EXPECT_FALSE(testStructuralMatch(t));
1244
}
1245

1246
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarBitfieldWidth) {
1247
  auto t = makeDecls<ObjCCategoryDecl>(
1248
      "@interface A @end @interface A() { int x: 1; } @end",
1249
      "@interface A @end @interface A() { int x: 2; } @end", Lang_OBJC,
1250
      objcCategoryDecl());
1251
  EXPECT_FALSE(testStructuralMatch(t));
1252
}
1253

1254
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarVisibility) {
1255
  auto t = makeDecls<ObjCCategoryDecl>(
1256
      "@interface A @end @interface A() { @public int x; } @end",
1257
      "@interface A @end @interface A() { @protected int x; } @end", Lang_OBJC,
1258
      objcCategoryDecl());
1259
  EXPECT_FALSE(testStructuralMatch(t));
1260
}
1261

1262
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarNumber) {
1263
  auto t = makeDecls<ObjCCategoryDecl>(
1264
      "@interface A @end @interface A() { int x; } @end",
1265
      "@interface A @end @interface A() {} @end", Lang_OBJC,
1266
      objcCategoryDecl());
1267
  EXPECT_FALSE(testStructuralMatch(t));
1268
}
1269

1270
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentIvarOrder) {
1271
  auto t = makeDecls<ObjCCategoryDecl>(
1272
      "@interface A @end @interface A() { int x; int y; } @end",
1273
      "@interface A @end @interface A() { int y; int x; } @end", Lang_OBJC,
1274
      objcCategoryDecl());
1275
  EXPECT_FALSE(testStructuralMatch(t));
1276
}
1277

1278
TEST_F(StructuralEquivalenceObjCCategoryTest, MatchingMethods) {
1279
  auto t = makeDecls<ObjCCategoryDecl>(
1280
      "@interface A @end @interface A(X) -(void)test; @end",
1281
      "@interface A @end @interface A(X) -(void)test; @end", Lang_OBJC,
1282
      objcCategoryDecl());
1283
  EXPECT_TRUE(testStructuralMatch(t));
1284
}
1285

1286
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodName) {
1287
  auto t = makeDecls<ObjCCategoryDecl>(
1288
      "@interface A @end @interface A(X) -(void)test; @end",
1289
      "@interface A @end @interface A(X) -(void)wasd; @end", Lang_OBJC,
1290
      objcCategoryDecl());
1291
  EXPECT_FALSE(testStructuralMatch(t));
1292

1293
  auto t2 = makeDecls<ObjCCategoryDecl>(
1294
      "@interface A @end @interface A(X) -(void)test:(int)x more:(int)y; @end",
1295
      "@interface A @end @interface A(X) -(void)test:(int)x :(int)y; @end",
1296
      Lang_OBJC, objcCategoryDecl());
1297
  EXPECT_FALSE(testStructuralMatch(t2));
1298
}
1299

1300
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodClassInstance) {
1301
  auto t = makeDecls<ObjCCategoryDecl>(
1302
      "@interface A @end @interface A(X) -(void)test; @end",
1303
      "@interface A @end @interface A(X) +(void)test; @end", Lang_OBJC,
1304
      objcCategoryDecl());
1305
  EXPECT_FALSE(testStructuralMatch(t));
1306
}
1307

1308
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodReturnType) {
1309
  auto t = makeDecls<ObjCCategoryDecl>(
1310
      "@interface A @end @interface A(X) -(void)test; @end",
1311
      "@interface A @end @interface A(X) -(int)test; @end", Lang_OBJC,
1312
      objcCategoryDecl());
1313
  EXPECT_FALSE(testStructuralMatch(t));
1314
}
1315

1316
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterType) {
1317
  auto t = makeDecls<ObjCCategoryDecl>(
1318
      "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1319
      "@interface A @end @interface A(X) -(void)test:(float)x; @end", Lang_OBJC,
1320
      objcCategoryDecl());
1321
  EXPECT_FALSE(testStructuralMatch(t));
1322
}
1323

1324
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodParameterName) {
1325
  auto t = makeDecls<ObjCCategoryDecl>(
1326
      "@interface A @end @interface A(X) -(void)test:(int)x; @end",
1327
      "@interface A @end @interface A(X) -(void)test:(int)y; @end", Lang_OBJC,
1328
      objcCategoryDecl());
1329
  EXPECT_TRUE(testStructuralMatch(t));
1330
}
1331

1332
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodNumber) {
1333
  auto t = makeDecls<ObjCCategoryDecl>(
1334
      "@interface A @end @interface A(X) -(void)test; @end",
1335
      "@interface A @end @interface A(X) @end", Lang_OBJC, objcCategoryDecl());
1336
  EXPECT_FALSE(testStructuralMatch(t));
1337
}
1338

1339
TEST_F(StructuralEquivalenceObjCCategoryTest, DifferentMethodOrder) {
1340
  auto t = makeDecls<ObjCCategoryDecl>(
1341
      "@interface A @end @interface A(X) -(void)u; -(void)v; @end",
1342
      "@interface A @end @interface A(X) -(void)v; -(void)u; @end", Lang_OBJC,
1343
      objcCategoryDecl());
1344
  EXPECT_FALSE(testStructuralMatch(t));
1345
}
1346

1347
struct StructuralEquivalenceTemplateTest : StructuralEquivalenceTest {};
1348

1349
TEST_F(StructuralEquivalenceTemplateTest, ExactlySameTemplates) {
1350
  auto t = makeNamedDecls("template <class T> struct foo;",
1351
                          "template <class T> struct foo;", Lang_CXX03);
1352
  EXPECT_TRUE(testStructuralMatch(t));
1353
}
1354

1355
TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgName) {
1356
  auto t = makeNamedDecls("template <class T> struct foo;",
1357
                          "template <class U> struct foo;", Lang_CXX03);
1358
  EXPECT_TRUE(testStructuralMatch(t));
1359
}
1360

1361
TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) {
1362
  auto t = makeNamedDecls("template <class T> struct foo;",
1363
                          "template <int T> struct foo;", Lang_CXX03);
1364
  EXPECT_FALSE(testStructuralMatch(t));
1365
}
1366

1367
TEST_F(StructuralEquivalenceTemplateTest, BitFieldDecl) {
1368
  const char *Code = "class foo { int a : 2; };";
1369
  auto t = makeNamedDecls(Code, Code, Lang_CXX03);
1370
  EXPECT_TRUE(testStructuralMatch(t));
1371
}
1372

1373
TEST_F(StructuralEquivalenceTemplateTest, BitFieldDeclDifferentWidth) {
1374
  auto t = makeNamedDecls("class foo { int a : 2; };",
1375
                          "class foo { int a : 4; };", Lang_CXX03);
1376
  EXPECT_FALSE(testStructuralMatch(t));
1377
}
1378

1379
TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDecl) {
1380
  const char *Code = "template <class T> class foo { int a : sizeof(T); };";
1381
  auto t = makeNamedDecls(Code, Code, Lang_CXX03);
1382
  EXPECT_TRUE(testStructuralMatch(t));
1383
}
1384

1385
TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal) {
1386
  auto t = makeNamedDecls(
1387
      "template <class A, class B> class foo { int a : sizeof(A); };",
1388
      "template <class A, class B> class foo { int a : sizeof(B); };",
1389
      Lang_CXX03);
1390
  EXPECT_FALSE(testStructuralMatch(t));
1391
}
1392

1393
TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal2) {
1394
  auto t = makeNamedDecls(
1395
      "template <class A> class foo { int a : sizeof(A); };",
1396
      "template <class A> class foo { int a : sizeof(A) + 1; };", Lang_CXX03);
1397
  EXPECT_FALSE(testStructuralMatch(t));
1398
}
1399

1400
TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) {
1401
  auto Decls = makeNamedDecls(
1402
      "template <bool b> struct foo {explicit(b) foo(int);};",
1403
      "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX20);
1404
  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
1405
      get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1406
  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
1407
      get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1408
  EXPECT_TRUE(testStructuralMatch(First, Second));
1409
}
1410

1411
TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolDifference) {
1412
  auto Decls = makeNamedDecls(
1413
      "template <bool b> struct foo {explicit(b) foo(int);};",
1414
      "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX20);
1415
  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
1416
      get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1417
  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
1418
      get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
1419
  EXPECT_FALSE(testStructuralMatch(First, Second));
1420
}
1421

1422
TEST_F(StructuralEquivalenceTemplateTest,
1423
       TemplateVsSubstTemplateTemplateParmInArgEq) {
1424
  auto t = makeDecls<ClassTemplateSpecializationDecl>(
1425
      R"(
1426
template <typename P1> class Arg { };
1427
template <template <typename PP1> class P1> class Primary { };
1428

1429
void f() {
1430
  // Make specialization with simple template.
1431
  Primary <Arg> A;
1432
}
1433
      )",
1434
      R"(
1435
template <typename P1> class Arg { };
1436
template <template <typename PP1> class P1> class Primary { };
1437

1438
template <template <typename PP1> class P1> class Templ {
1439
  void f() {
1440
    // Make specialization with substituted template template param.
1441
    Primary <P1> A;
1442
  };
1443
};
1444

1445
// Instantiate with substitution Arg into P1.
1446
template class Templ <Arg>;
1447
      )",
1448
      Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1449
  EXPECT_TRUE(testStructuralMatch(t));
1450
}
1451

1452
TEST_F(StructuralEquivalenceTemplateTest,
1453
       TemplateVsSubstTemplateTemplateParmInArgNotEq) {
1454
  auto t = makeDecls<ClassTemplateSpecializationDecl>(
1455
      R"(
1456
template <typename P1> class Arg { };
1457
template <template <typename PP1> class P1> class Primary { };
1458

1459
void f() {
1460
  // Make specialization with simple template.
1461
  Primary <Arg> A;
1462
}
1463
      )",
1464
      R"(
1465
// Arg is different from the other, this should cause non-equivalence.
1466
template <typename P1> class Arg { int X; };
1467
template <template <typename PP1> class P1> class Primary { };
1468

1469
template <template <typename PP1> class P1> class Templ {
1470
  void f() {
1471
    // Make specialization with substituted template template param.
1472
    Primary <P1> A;
1473
  };
1474
};
1475

1476
// Instantiate with substitution Arg into P1.
1477
template class Templ <Arg>;
1478
      )",
1479
      Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1480
  EXPECT_FALSE(testStructuralMatch(t));
1481
}
1482

1483
struct StructuralEquivalenceDependentTemplateArgsTest
1484
    : StructuralEquivalenceTemplateTest {};
1485

1486
TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1487
       SameStructsInDependentArgs) {
1488
  std::string Code =
1489
      R"(
1490
      template <typename>
1491
      struct S1;
1492

1493
      template <typename>
1494
      struct enable_if;
1495

1496
      struct S
1497
      {
1498
        template <typename T, typename enable_if<S1<T>>::type>
1499
        void f();
1500
      };
1501
      )";
1502
  auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1503
                                           functionTemplateDecl(hasName("f")));
1504
  EXPECT_TRUE(testStructuralMatch(t));
1505
}
1506

1507
TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1508
       DifferentStructsInDependentArgs) {
1509
  std::string Code =
1510
      R"(
1511
      template <typename>
1512
      struct S1;
1513

1514
      template <typename>
1515
      struct S2;
1516

1517
      template <typename>
1518
      struct enable_if;
1519
      )";
1520
  auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1521
      struct S
1522
      {
1523
        template <typename T, typename enable_if<S1<T>>::type>
1524
        void f();
1525
      };
1526
      )",
1527
                                           Code + R"(
1528
      struct S
1529
      {
1530
        template <typename T, typename enable_if<S2<T>>::type>
1531
        void f();
1532
      };
1533
      )",
1534
                                           Lang_CXX11,
1535
                                           functionTemplateDecl(hasName("f")));
1536
  EXPECT_FALSE(testStructuralMatch(t));
1537
}
1538

1539
TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1540
       SameStructsInDependentScopeDeclRefExpr) {
1541
  std::string Code =
1542
      R"(
1543
      template <typename>
1544
      struct S1;
1545

1546
      template <bool>
1547
      struct enable_if;
1548

1549
      struct S
1550
      {
1551
        template <typename T, typename enable_if<S1<T>::value>::type>
1552
        void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1553
      };
1554
      )";
1555
  auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
1556
                                           functionTemplateDecl(hasName("f")));
1557
  EXPECT_TRUE(testStructuralMatch(t));
1558
}
1559

1560
TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1561
       DifferentStructsInDependentScopeDeclRefExpr) {
1562
  std::string Code =
1563
      R"(
1564
      template <typename>
1565
      struct S1;
1566

1567
      template <typename>
1568
      struct S2;
1569

1570
      template <bool>
1571
      struct enable_if;
1572
      )";
1573
  auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1574
      struct S
1575
      {
1576
        template <typename T, typename enable_if<S1<T>::value>::type>
1577
        void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1578
      };
1579
      )",
1580
                                           Code + R"(
1581
      struct S
1582
      {
1583
        template <typename T, typename enable_if<S2<T>::value>::type>
1584
        void f();
1585
      };
1586
      )",
1587
                                           Lang_CXX03,
1588
                                           functionTemplateDecl(hasName("f")));
1589
  EXPECT_FALSE(testStructuralMatch(t));
1590
}
1591

1592
TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
1593
       DifferentValueInDependentScopeDeclRefExpr) {
1594
  std::string Code =
1595
      R"(
1596
      template <typename>
1597
      struct S1;
1598

1599
      template <bool>
1600
      struct enable_if;
1601
      )";
1602
  auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
1603
      struct S
1604
      {
1605
        template <typename T, typename enable_if<S1<T>::value1>::type>
1606
        void f();   // DependentScopeDeclRefExpr:^^^^^^^^^^^^
1607
      };
1608
      )",
1609
                                           Code + R"(
1610
      struct S
1611
      {
1612
        template <typename T, typename enable_if<S1<T>::value2>::type>
1613
        void f();
1614
      };
1615
      )",
1616
                                           Lang_CXX03,
1617
                                           functionTemplateDecl(hasName("f")));
1618
  EXPECT_FALSE(testStructuralMatch(t));
1619
}
1620

1621
TEST_F(
1622
    StructuralEquivalenceTemplateTest,
1623
    ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual) {
1624
  auto t = makeDecls<ClassTemplateSpecializationDecl>(
1625
      R"(
1626
      template <class T> struct Primary {};
1627
      namespace N {
1628
        struct Arg;
1629
      }
1630
      // Explicit instantiation with qualified name.
1631
      template struct Primary<N::Arg>;
1632
      )",
1633
      R"(
1634
      template <class T> struct Primary {};
1635
      namespace N {
1636
        struct Arg;
1637
      }
1638
      using namespace N;
1639
      // Explicit instantiation with UNqualified name.
1640
      template struct Primary<Arg>;
1641
      )",
1642
      Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1643
  EXPECT_TRUE(testStructuralMatch(t));
1644
}
1645

1646
TEST_F(
1647
    StructuralEquivalenceTemplateTest,
1648
    ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs) {
1649
  auto t = makeDecls<ClassTemplateSpecializationDecl>(
1650
      R"(
1651
      template <class T> struct Primary {};
1652
      namespace N {
1653
        struct Arg { int a; };
1654
      }
1655
      // Explicit instantiation with qualified name.
1656
      template struct Primary<N::Arg>;
1657
      )",
1658
      R"(
1659
      template <class T> struct Primary {};
1660
      namespace N {
1661
        // This struct is not equivalent with the other in the prev TU.
1662
        struct Arg { double b; }; // -- Field mismatch.
1663
      }
1664
      using namespace N;
1665
      // Explicit instantiation with UNqualified name.
1666
      template struct Primary<Arg>;
1667
      )",
1668
      Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1669
  EXPECT_FALSE(testStructuralMatch(t));
1670
}
1671

1672
TEST_F(
1673
    StructuralEquivalenceTemplateTest,
1674
    ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual) {
1675
  auto t = makeDecls<ClassTemplateSpecializationDecl>(
1676
      R"(
1677
      template <template <class> class T> struct Primary {};
1678
      namespace N {
1679
        template <class T> struct Arg;
1680
      }
1681
      // Explicit instantiation with qualified name.
1682
      template struct Primary<N::Arg>;
1683
      )",
1684
      R"(
1685
      template <template <class> class T> struct Primary {};
1686
      namespace N {
1687
        template <class T> struct Arg;
1688
      }
1689
      using namespace N;
1690
      // Explicit instantiation with UNqualified name.
1691
      template struct Primary<Arg>;
1692
      )",
1693
      Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1694
  EXPECT_TRUE(testStructuralMatch(t));
1695
}
1696

1697
TEST_F(
1698
    StructuralEquivalenceTemplateTest,
1699
    ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs) {
1700
  auto t = makeDecls<ClassTemplateSpecializationDecl>(
1701
      R"(
1702
      template <template <class> class T> struct Primary {};
1703
      namespace N {
1704
        template <class T> struct Arg { int a; };
1705
      }
1706
      // Explicit instantiation with qualified name.
1707
      template struct Primary<N::Arg>;
1708
      )",
1709
      R"(
1710
      template <template <class> class T> struct Primary {};
1711
      namespace N {
1712
        // This template is not equivalent with the other in the prev TU.
1713
        template <class T> struct Arg { double b; }; // -- Field mismatch.
1714
      }
1715
      using namespace N;
1716
      // Explicit instantiation with UNqualified name.
1717
      template struct Primary<Arg>;
1718
      )",
1719
      Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1720
  EXPECT_FALSE(testStructuralMatch(t));
1721
}
1722

1723
TEST_F(StructuralEquivalenceTemplateTest,
1724
       IgnoreTemplateParmDepthAtTemplateTypeParmDecl) {
1725
  auto Decls = makeDecls<ClassTemplateDecl>(
1726
      R"(
1727
        template<class> struct A;
1728
      )",
1729
      R"(
1730
        template<class> struct S {
1731
          template<class> friend struct A;
1732
        };
1733
      )",
1734
      Lang_CXX03, classTemplateDecl(hasName("A")),
1735
      classTemplateDecl(hasName("A")));
1736
  EXPECT_TRUE(testStructuralMatch(Decls));
1737
  EXPECT_TRUE(testStructuralMatch(Decls, true));
1738
}
1739

1740
TEST_F(StructuralEquivalenceTemplateTest,
1741
       IgnoreTemplateParmDepthAtNonTypeTemplateParmDecl) {
1742
  auto Decls = makeDecls<ClassTemplateDecl>(
1743
      R"(
1744
        template<class T, T U> struct A;
1745
      )",
1746
      R"(
1747
        template<class T> struct S {
1748
          template<class P, P Q> friend struct A;
1749
        };
1750
      )",
1751
      Lang_CXX03, classTemplateDecl(hasName("A")),
1752
      classTemplateDecl(hasName("A")));
1753
  EXPECT_FALSE(testStructuralMatch(Decls));
1754
  EXPECT_TRUE(testStructuralMatch(Decls, /*IgnoreTemplateParmDepth=*/true));
1755
}
1756

1757
TEST_F(
1758
    StructuralEquivalenceTemplateTest,
1759
    ClassTemplSpecWithInequivalentShadowedTemplArg) {
1760
  auto t = makeDecls<ClassTemplateSpecializationDecl>(
1761
      R"(
1762
      template <template <class> class T> struct Primary {};
1763
      template <class T> struct Arg { int a; };
1764
      // Explicit instantiation with ::Arg
1765
      template struct Primary<Arg>;
1766
      )",
1767
      R"(
1768
      template <template <class> class T> struct Primary {};
1769
      template <class T> struct Arg { int a; };
1770
      namespace N {
1771
        // This template is not equivalent with the other in the global scope.
1772
        template <class T> struct Arg { double b; }; // -- Field mismatch.
1773
        // Explicit instantiation with N::Arg which shadows ::Arg
1774
        template struct Primary<Arg>;
1775
      }
1776
      )",
1777
      Lang_CXX03, classTemplateSpecializationDecl(hasName("Primary")));
1778
  EXPECT_FALSE(testStructuralMatch(t));
1779
}
1780
struct StructuralEquivalenceCacheTest : public StructuralEquivalenceTest {
1781
  llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls;
1782

1783
  template <typename NodeType, typename MatcherType>
1784
  std::pair<NodeType *, NodeType *>
1785
  findDeclPair(std::tuple<TranslationUnitDecl *, TranslationUnitDecl *> TU,
1786
               MatcherType M) {
1787
    NodeType *D0 = FirstDeclMatcher<NodeType>().match(get<0>(TU), M);
1788
    NodeType *D1 = FirstDeclMatcher<NodeType>().match(get<1>(TU), M);
1789
    return {D0, D1};
1790
  }
1791

1792
  template <typename NodeType>
1793
  bool isInNonEqCache(std::pair<NodeType *, NodeType *> D) {
1794
    return NonEquivalentDecls.count(D) > 0;
1795
  }
1796
};
1797

1798
TEST_F(StructuralEquivalenceCacheTest, SimpleNonEq) {
1799
  auto TU = makeTuDecls(
1800
      R"(
1801
      class A {};
1802
      class B {};
1803
      void x(A, A);
1804
      )",
1805
      R"(
1806
      class A {};
1807
      class B {};
1808
      void x(A, B);
1809
      )",
1810
      Lang_CXX03);
1811

1812
  StructuralEquivalenceContext Ctx(
1813
      get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1814
      NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1815

1816
  auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")));
1817
  EXPECT_FALSE(Ctx.IsEquivalent(X.first, X.second));
1818

1819
  EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1820
      TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1821
  EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1822
      TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1823
}
1824

1825
TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
1826
  auto TU = makeTuDecls(
1827
      R"(
1828
      bool x() { return true; }
1829
      )",
1830
      R"(
1831
      bool x() { return false; }
1832
      )",
1833
      Lang_CXX03);
1834

1835
  StructuralEquivalenceContext Ctx(
1836
      get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1837
      NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1838

1839
  auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")));
1840
  EXPECT_FALSE(Ctx.IsEquivalent(X.first->getBody(), X.second->getBody()));
1841

1842
}
1843

1844
TEST_F(StructuralEquivalenceCacheTest, VarDeclNoEq) {
1845
  auto TU = makeTuDecls(
1846
      R"(
1847
      int p;
1848
      )",
1849
      R"(
1850
      int q;
1851
      )",
1852
      Lang_CXX03);
1853

1854
  StructuralEquivalenceContext Ctx(
1855
      get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1856
      NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1857

1858
  auto Var = findDeclPair<VarDecl>(TU, varDecl());
1859
  EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1860
}
1861

1862
TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) {
1863
  auto TU = makeTuDecls(
1864
      R"(
1865
      int p;
1866
      )",
1867
      R"(
1868
      static int p;
1869
      )",
1870
      Lang_CXX03);
1871

1872
  StructuralEquivalenceContext Ctx(
1873
      get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1874
      NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1875

1876
  auto Var = findDeclPair<VarDecl>(TU, varDecl());
1877
  EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1878
}
1879

1880
TEST_F(StructuralEquivalenceCacheTest,
1881
       NonTypeTemplateParmWithDifferentPositionNoEq) {
1882
  auto TU = makeTuDecls(
1883
      R"(
1884
      template<int T>
1885
      struct A {
1886
        template<int U>
1887
        void foo() {}
1888
      };
1889
      )",
1890
      R"(
1891
      template<int U>
1892
      struct A {
1893
        template<int V, int T>
1894
        void foo() {}
1895
      };
1896
      )",
1897
      Lang_CXX03);
1898

1899
  StructuralEquivalenceContext Ctx(
1900
      get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1901
      NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1902

1903
  auto NTTP = findDeclPair<NonTypeTemplateParmDecl>(
1904
      TU, nonTypeTemplateParmDecl(hasName("T")));
1905
  EXPECT_FALSE(Ctx.IsEquivalent(NTTP.first, NTTP.second));
1906
}
1907

1908
TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
1909
  auto TU = makeTuDecls(
1910
      R"(
1911
      int p = 1;
1912
      )",
1913
      R"(
1914
      int p = 2;
1915
      )",
1916
      Lang_CXX03);
1917

1918
  StructuralEquivalenceContext Ctx(
1919
      get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1920
      NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1921

1922
  auto Var = findDeclPair<VarDecl>(TU, varDecl());
1923
  EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1924
}
1925

1926
TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
1927
  auto TU = makeTuDecls(
1928
      R"(
1929
      class A {};
1930
      class B { int i; };
1931
      void x(A *);
1932
      void y(A *);
1933
      class C {
1934
        friend void x(A *);
1935
        friend void y(A *);
1936
      };
1937
      )",
1938
      R"(
1939
      class A {};
1940
      class B { int i; };
1941
      void x(A *);
1942
      void y(B *);
1943
      class C {
1944
        friend void x(A *);
1945
        friend void y(B *);
1946
      };
1947
      )",
1948
      Lang_CXX03);
1949

1950
  StructuralEquivalenceContext Ctx(
1951
      get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1952
      NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1953

1954
  auto C = findDeclPair<CXXRecordDecl>(
1955
      TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
1956
  EXPECT_FALSE(Ctx.IsEquivalent(C.first, C.second));
1957

1958
  EXPECT_FALSE(isInNonEqCache(C));
1959
  EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1960
      TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
1961
  EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1962
      TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
1963
  EXPECT_FALSE(isInNonEqCache(
1964
      findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
1965
  EXPECT_FALSE(isInNonEqCache(
1966
      findDeclPair<FunctionDecl>(TU, functionDecl(hasName("y")))));
1967
}
1968

1969
TEST_F(StructuralEquivalenceCacheTest, Cycle) {
1970
  auto TU = makeTuDecls(
1971
      R"(
1972
      class C;
1973
      class A { C *c; };
1974
      void x(A *);
1975
      class C {
1976
        friend void x(A *);
1977
      };
1978
      )",
1979
      R"(
1980
      class C;
1981
      class A { C *c; };
1982
      void x(A *);
1983
      class C {
1984
        friend void x(A *);
1985
      };
1986
      )",
1987
      Lang_CXX03);
1988

1989
  StructuralEquivalenceContext Ctx(
1990
      get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1991
      NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1992

1993
  auto C = findDeclPair<CXXRecordDecl>(
1994
      TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
1995
  EXPECT_TRUE(Ctx.IsEquivalent(C.first, C.second));
1996

1997
  EXPECT_FALSE(isInNonEqCache(C));
1998
  EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
1999
      TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
2000
  EXPECT_FALSE(isInNonEqCache(
2001
      findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
2002
}
2003

2004
struct StructuralEquivalenceStmtTest : StructuralEquivalenceTest {};
2005

2006
/// Fallback matcher to be used only when there is no specific matcher for a
2007
/// Expr subclass. Remove this once all Expr subclasses have their own matcher.
2008
static auto &fallbackExprMatcher = expr;
2009

2010
TEST_F(StructuralEquivalenceStmtTest, AddrLabelExpr) {
2011
  auto t = makeWrappedStmts("lbl: &&lbl;", "lbl: &&lbl;", Lang_CXX03,
2012
                            addrLabelExpr());
2013
  EXPECT_TRUE(testStructuralMatch(t));
2014
}
2015

2016
TEST_F(StructuralEquivalenceStmtTest, AddrLabelExprDifferentLabel) {
2017
  auto t = makeWrappedStmts("lbl1: lbl2: &&lbl1;", "lbl1: lbl2: &&lbl2;",
2018
                            Lang_CXX03, addrLabelExpr());
2019
  // FIXME: Should be false. LabelDecl are incorrectly matched.
2020
  EXPECT_TRUE(testStructuralMatch(t));
2021
}
2022

2023
static const std::string MemoryOrderSrc = R"(
2024
enum memory_order {
2025
  memory_order_relaxed,
2026
  memory_order_consume,
2027
  memory_order_acquire,
2028
  memory_order_release,
2029
  memory_order_acq_rel,
2030
  memory_order_seq_cst
2031
};
2032
)";
2033

2034
TEST_F(StructuralEquivalenceStmtTest, AtomicExpr) {
2035
  std::string Prefix = "char a, b; " + MemoryOrderSrc;
2036
  auto t = makeStmts(
2037
      Prefix +
2038
          "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
2039
      Prefix +
2040
          "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
2041
      Lang_CXX03, atomicExpr());
2042
  EXPECT_TRUE(testStructuralMatch(t));
2043
}
2044

2045
TEST_F(StructuralEquivalenceStmtTest, AtomicExprDifferentOp) {
2046
  std::string Prefix = "char a, b; " + MemoryOrderSrc;
2047
  auto t = makeStmts(
2048
      Prefix +
2049
          "void wrapped() { __atomic_load(&a, &b, memory_order_seq_cst); }",
2050
      Prefix +
2051
          "void wrapped() { __atomic_store(&a, &b, memory_order_seq_cst); }",
2052
      Lang_CXX03, atomicExpr());
2053
  EXPECT_FALSE(testStructuralMatch(t));
2054
}
2055

2056
TEST_F(StructuralEquivalenceStmtTest, BinaryOperator) {
2057
  auto t = makeWrappedStmts("1 + 1", "1 + 1", Lang_CXX03, binaryOperator());
2058
  EXPECT_TRUE(testStructuralMatch(t));
2059
}
2060

2061
TEST_F(StructuralEquivalenceStmtTest, BinaryOperatorDifferentOps) {
2062
  auto t = makeWrappedStmts("1 + 1", "1 - 1", Lang_CXX03, binaryOperator());
2063
  EXPECT_FALSE(testStructuralMatch(t));
2064
}
2065

2066
TEST_F(StructuralEquivalenceStmtTest, CallExpr) {
2067
  std::string Src = "int call(); int wrapped() { call(); }";
2068
  auto t = makeStmts(Src, Src, Lang_CXX03, callExpr());
2069
  EXPECT_TRUE(testStructuralMatch(t));
2070
}
2071

2072
TEST_F(StructuralEquivalenceStmtTest, CallExprDifferentCallee) {
2073
  std::string FunctionSrc = "int func1(); int func2();\n";
2074
  auto t = makeStmts(FunctionSrc + "void wrapper() { func1(); }",
2075
                     FunctionSrc + "void wrapper() { func2(); }", Lang_CXX03,
2076
                     callExpr());
2077
  EXPECT_FALSE(testStructuralMatch(t));
2078
}
2079

2080
TEST_F(StructuralEquivalenceStmtTest, CharacterLiteral) {
2081
  auto t = makeWrappedStmts("'a'", "'a'", Lang_CXX03, characterLiteral());
2082
  EXPECT_TRUE(testStructuralMatch(t));
2083
}
2084

2085
TEST_F(StructuralEquivalenceStmtTest, CharacterLiteralDifferentValues) {
2086
  auto t = makeWrappedStmts("'a'", "'b'", Lang_CXX03, characterLiteral());
2087
  EXPECT_FALSE(testStructuralMatch(t));
2088
}
2089

2090
TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExpr) {
2091
  auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_lvalue_expr(1)",
2092
                            Lang_CXX03, fallbackExprMatcher());
2093
  EXPECT_TRUE(testStructuralMatch(t));
2094
}
2095

2096
TEST_F(StructuralEquivalenceStmtTest, ExpressionTraitExprDifferentKind) {
2097
  auto t = makeWrappedStmts("__is_lvalue_expr(1)", "__is_rvalue_expr(1)",
2098
                            Lang_CXX03, fallbackExprMatcher());
2099
  EXPECT_FALSE(testStructuralMatch(t));
2100
}
2101

2102
TEST_F(StructuralEquivalenceStmtTest, FloatingLiteral) {
2103
  auto t = makeWrappedStmts("1.0", "1.0", Lang_CXX03, fallbackExprMatcher());
2104
  EXPECT_TRUE(testStructuralMatch(t));
2105
}
2106

2107
TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentSpelling) {
2108
  auto t = makeWrappedStmts("0x10.1p0", "16.0625", Lang_CXX17,
2109
                            fallbackExprMatcher());
2110
  // Same value but with different spelling is equivalent.
2111
  EXPECT_TRUE(testStructuralMatch(t));
2112
}
2113

2114
TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentType) {
2115
  auto t = makeWrappedStmts("1.0", "1.0f", Lang_CXX03, fallbackExprMatcher());
2116
  EXPECT_FALSE(testStructuralMatch(t));
2117
}
2118

2119
TEST_F(StructuralEquivalenceStmtTest, FloatingLiteralDifferentValue) {
2120
  auto t = makeWrappedStmts("1.01", "1.0", Lang_CXX03, fallbackExprMatcher());
2121
  EXPECT_FALSE(testStructuralMatch(t));
2122
}
2123

2124
TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSame) {
2125
  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2126
                            "_Generic(0u, unsigned int: 0, float: 1)", Lang_C99,
2127
                            genericSelectionExpr());
2128
  EXPECT_TRUE(testStructuralMatch(t));
2129
}
2130

2131
TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprSignsDiffer) {
2132
  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2133
                            "_Generic(0, int: 0, float: 1)", Lang_C99,
2134
                            genericSelectionExpr());
2135
  EXPECT_FALSE(testStructuralMatch(t));
2136
}
2137

2138
TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprOrderDiffers) {
2139
  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
2140
                            "_Generic(0u, float: 1, unsigned int: 0)", Lang_C99,
2141
                            genericSelectionExpr());
2142
  EXPECT_FALSE(testStructuralMatch(t));
2143
}
2144

2145
TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprDependentResultSame) {
2146
  auto t = makeStmts(
2147
      R"(
2148
      template <typename T>
2149
      void f() {
2150
        T x;
2151
        (void)_Generic(x, int: 0, float: 1);
2152
      }
2153
      void g() { f<int>(); }
2154
      )",
2155
      R"(
2156
      template <typename T>
2157
      void f() {
2158
        T x;
2159
        (void)_Generic(x, int: 0, float: 1);
2160
      }
2161
      void g() { f<int>(); }
2162
      )",
2163
      Lang_CXX03, genericSelectionExpr());
2164
  EXPECT_TRUE(testStructuralMatch(t));
2165
}
2166

2167
TEST_F(StructuralEquivalenceStmtTest,
2168
       GenericSelectionExprDependentResultOrderDiffers) {
2169
  auto t = makeStmts(
2170
      R"(
2171
      template <typename T>
2172
      void f() {
2173
        T x;
2174
        (void)_Generic(x, float: 1, int: 0);
2175
      }
2176
      void g() { f<int>(); }
2177
      )",
2178
      R"(
2179
      template <typename T>
2180
      void f() {
2181
        T x;
2182
        (void)_Generic(x, int: 0, float: 1);
2183
      }
2184
      void g() { f<int>(); }
2185
      )",
2186
      Lang_CXX03, genericSelectionExpr());
2187

2188
  EXPECT_FALSE(testStructuralMatch(t));
2189
}
2190
TEST_F(StructuralEquivalenceStmtTest, IntegerLiteral) {
2191
  auto t = makeWrappedStmts("1", "1", Lang_CXX03, integerLiteral());
2192
  EXPECT_TRUE(testStructuralMatch(t));
2193
}
2194

2195
TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentSpelling) {
2196
  auto t = makeWrappedStmts("1", "0x1", Lang_CXX03, integerLiteral());
2197
  // Same value but with different spelling is equivalent.
2198
  EXPECT_TRUE(testStructuralMatch(t));
2199
}
2200

2201
TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentValue) {
2202
  auto t = makeWrappedStmts("1", "2", Lang_CXX03, integerLiteral());
2203
  EXPECT_FALSE(testStructuralMatch(t));
2204
}
2205

2206
TEST_F(StructuralEquivalenceStmtTest, IntegerLiteralDifferentTypes) {
2207
  auto t = makeWrappedStmts("1", "1L", Lang_CXX03, integerLiteral());
2208
  EXPECT_FALSE(testStructuralMatch(t));
2209
}
2210

2211
TEST_F(StructuralEquivalenceStmtTest, MemberExpr) {
2212
  std::string ClassSrc = "struct C { int a; int b; };";
2213
  auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }",
2214
                     ClassSrc + "int wrapper() { C c; return c.a; }",
2215
                     Lang_CXX03, memberExpr());
2216
  EXPECT_TRUE(testStructuralMatch(t));
2217
}
2218

2219
TEST_F(StructuralEquivalenceStmtTest, MemberExprDifferentMember) {
2220
  std::string ClassSrc = "struct C { int a; int b; };";
2221
  auto t = makeStmts(ClassSrc + "int wrapper() { C c; return c.a; }",
2222
                     ClassSrc + "int wrapper() { C c; return c.b; }",
2223
                     Lang_CXX03, memberExpr());
2224
  EXPECT_FALSE(testStructuralMatch(t));
2225
}
2226

2227
TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteral) {
2228
  auto t =
2229
      makeWrappedStmts("@\"a\"", "@\"a\"", Lang_OBJCXX, fallbackExprMatcher());
2230
  EXPECT_TRUE(testStructuralMatch(t));
2231
}
2232

2233
TEST_F(StructuralEquivalenceStmtTest, ObjCStringLiteralDifferentContent) {
2234
  auto t =
2235
      makeWrappedStmts("@\"a\"", "@\"b\"", Lang_OBJCXX, fallbackExprMatcher());
2236
  EXPECT_FALSE(testStructuralMatch(t));
2237
}
2238

2239
TEST_F(StructuralEquivalenceStmtTest, StringLiteral) {
2240
  auto t = makeWrappedStmts("\"a\"", "\"a\"", Lang_CXX03, stringLiteral());
2241
  EXPECT_TRUE(testStructuralMatch(t));
2242
}
2243

2244
TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentContent) {
2245
  auto t = makeWrappedStmts("\"a\"", "\"b\"", Lang_CXX03, stringLiteral());
2246
  EXPECT_FALSE(testStructuralMatch(t));
2247
}
2248

2249
TEST_F(StructuralEquivalenceStmtTest, StringLiteralDifferentLength) {
2250
  auto t = makeWrappedStmts("\"a\"", "\"aa\"", Lang_CXX03, stringLiteral());
2251
  EXPECT_FALSE(testStructuralMatch(t));
2252
}
2253

2254
TEST_F(StructuralEquivalenceStmtTest, TypeTraitExpr) {
2255
  auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(int)", Lang_CXX03,
2256
                            fallbackExprMatcher());
2257
  EXPECT_TRUE(testStructuralMatch(t));
2258
}
2259

2260
TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentType) {
2261
  auto t = makeWrappedStmts("__is_pod(int)", "__is_pod(long)", Lang_CXX03,
2262
                            fallbackExprMatcher());
2263
  EXPECT_FALSE(testStructuralMatch(t));
2264
}
2265

2266
TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTrait) {
2267
  auto t = makeWrappedStmts(
2268
      "__is_pod(int)", "__is_trivially_constructible(int)", Lang_CXX03, expr());
2269
  EXPECT_FALSE(testStructuralMatch(t));
2270
}
2271

2272
TEST_F(StructuralEquivalenceStmtTest, TypeTraitExprDifferentTraits) {
2273
  auto t = makeWrappedStmts("__is_constructible(int)",
2274
                            "__is_constructible(int, int)", Lang_CXX03, expr());
2275
  EXPECT_FALSE(testStructuralMatch(t));
2276
}
2277

2278
TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExpr) {
2279
  auto t = makeWrappedStmts("sizeof(int)", "sizeof(int)", Lang_CXX03,
2280
                            unaryExprOrTypeTraitExpr());
2281
  EXPECT_TRUE(testStructuralMatch(t));
2282
}
2283

2284
TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentKind) {
2285
  auto t = makeWrappedStmts("sizeof(int)", "alignof(long)", Lang_CXX11,
2286
                            unaryExprOrTypeTraitExpr());
2287
  EXPECT_FALSE(testStructuralMatch(t));
2288
}
2289

2290
TEST_F(StructuralEquivalenceStmtTest, UnaryExprOrTypeTraitExprDifferentType) {
2291
  auto t = makeWrappedStmts("sizeof(int)", "sizeof(long)", Lang_CXX03,
2292
                            unaryExprOrTypeTraitExpr());
2293
  EXPECT_FALSE(testStructuralMatch(t));
2294
}
2295

2296
TEST_F(StructuralEquivalenceStmtTest, UnaryOperator) {
2297
  auto t = makeWrappedStmts("+1", "+1", Lang_CXX03, unaryOperator());
2298
  EXPECT_TRUE(testStructuralMatch(t));
2299
}
2300

2301
TEST_F(StructuralEquivalenceStmtTest, UnaryOperatorDifferentOps) {
2302
  auto t = makeWrappedStmts("+1", "-1", Lang_CXX03, unaryOperator());
2303
  EXPECT_FALSE(testStructuralMatch(t));
2304
}
2305

2306
TEST_F(StructuralEquivalenceStmtTest,
2307
       CXXOperatorCallExprVsUnaryBinaryOperator) {
2308
  auto t = makeNamedDecls(
2309
      R"(
2310
      template <typename T, T x>
2311
      class A;
2312
      template <typename T, T x, T y>
2313
      void foo(
2314
        A<T, x + y>,
2315
        A<T, x - y>,
2316
        A<T, -x>,
2317
        A<T, x * y>,
2318
        A<T, *x>,
2319
        A<T, x / y>,
2320
        A<T, x % y>,
2321
        A<T, x ^ y>,
2322
        A<T, x & y>,
2323
        A<T, &x>,
2324
        A<T, x | y>,
2325
        A<T, ~x>,
2326
        A<T, !x>,
2327
        A<T, x < y>,
2328
        A<T, (x > y)>,
2329
        A<T, x << y>,
2330
        A<T, (x >> y)>,
2331
        A<T, x == y>,
2332
        A<T, x != y>,
2333
        A<T, x <= y>,
2334
        A<T, x >= y>,
2335
        A<T, x <=> y>,
2336
        A<T, x && y>,
2337
        A<T, x || y>,
2338
        A<T, ++x>,
2339
        A<T, --x>,
2340
        A<T, (x , y)>,
2341
        A<T, x ->* y>,
2342
        A<T, x -> y>
2343
      );
2344
      )",
2345
      R"(
2346
      struct Bar {
2347
        Bar& operator=(Bar&);
2348
        Bar& operator->();
2349
      };
2350

2351
      Bar& operator+(Bar&, Bar&);
2352
      Bar& operator+(Bar&);
2353
      Bar& operator-(Bar&, Bar&);
2354
      Bar& operator-(Bar&);
2355
      Bar& operator*(Bar&, Bar&);
2356
      Bar& operator*(Bar&);
2357
      Bar& operator/(Bar&, Bar&);
2358
      Bar& operator%(Bar&, Bar&);
2359
      Bar& operator^(Bar&, Bar&);
2360
      Bar& operator&(Bar&, Bar&);
2361
      Bar& operator&(Bar&);
2362
      Bar& operator|(Bar&, Bar&);
2363
      Bar& operator~(Bar&);
2364
      Bar& operator!(Bar&);
2365
      Bar& operator<(Bar&, Bar&);
2366
      Bar& operator>(Bar&, Bar&);
2367
      Bar& operator+=(Bar&, Bar&);
2368
      Bar& operator-=(Bar&, Bar&);
2369
      Bar& operator*=(Bar&, Bar&);
2370
      Bar& operator/=(Bar&, Bar&);
2371
      Bar& operator%=(Bar&, Bar&);
2372
      Bar& operator^=(Bar&, Bar&);
2373
      Bar& operator&=(Bar&, Bar&);
2374
      Bar& operator|=(Bar&, Bar&);
2375
      Bar& operator<<(Bar&, Bar&);
2376
      Bar& operator>>(Bar&, Bar&);
2377
      Bar& operator<<=(Bar&, Bar&);
2378
      Bar& operator>>=(Bar&, Bar&);
2379
      Bar& operator==(Bar&, Bar&);
2380
      Bar& operator!=(Bar&, Bar&);
2381
      Bar& operator<=(Bar&, Bar&);
2382
      Bar& operator>=(Bar&, Bar&);
2383
      Bar& operator<=>(Bar&, Bar&);
2384
      Bar& operator&&(Bar&, Bar&);
2385
      Bar& operator||(Bar&, Bar&);
2386
      Bar& operator++(Bar&);
2387
      Bar& operator--(Bar&);
2388
      Bar& operator,(Bar&, Bar&);
2389
      Bar& operator->*(Bar&, Bar&);
2390

2391
      template <typename T, T x>
2392
      class A;
2393
      template <typename T, T x, T y>
2394
      void foo(
2395
        A<T, x + y>,
2396
        A<T, x - y>,
2397
        A<T, -x>,
2398
        A<T, x * y>,
2399
        A<T, *x>,
2400
        A<T, x / y>,
2401
        A<T, x % y>,
2402
        A<T, x ^ y>,
2403
        A<T, x & y>,
2404
        A<T, &x>,
2405
        A<T, x | y>,
2406
        A<T, ~x>,
2407
        A<T, !x>,
2408
        A<T, x < y>,
2409
        A<T, (x > y)>,
2410
        A<T, x << y>,
2411
        A<T, (x >> y)>,
2412
        A<T, x == y>,
2413
        A<T, x != y>,
2414
        A<T, x <= y>,
2415
        A<T, x >= y>,
2416
        A<T, x <=> y>,
2417
        A<T, x && y>,
2418
        A<T, x || y>,
2419
        A<T, ++x>,
2420
        A<T, --x>,
2421
        A<T, (x , y)>,
2422
        A<T, x ->* y>,
2423
        A<T, x -> y>
2424
      );
2425
      )",
2426
      Lang_CXX20);
2427
  EXPECT_TRUE(testStructuralMatch(t));
2428
}
2429

2430
TEST_F(StructuralEquivalenceStmtTest,
2431
       CXXOperatorCallExprVsUnaryBinaryOperatorNe) {
2432
  auto t = makeNamedDecls(
2433
      R"(
2434
      template <typename T, T x>
2435
      class A;
2436
      template <typename T, T x, T y>
2437
      void foo(
2438
        A<T, x + y>
2439
      );
2440
      )",
2441
      R"(
2442
      struct Bar;
2443

2444
      Bar& operator-(Bar&, Bar&);
2445

2446
      template <typename T, T x>
2447
      class A;
2448
      template <typename T, T x, T y>
2449
      void foo(
2450
        A<T, x - y>
2451
      );
2452
      )",
2453
      Lang_CXX11);
2454
  EXPECT_FALSE(testStructuralMatch(t));
2455
}
2456

2457
TEST_F(StructuralEquivalenceStmtTest, NonTypeTemplateParm) {
2458
  auto t = makeNamedDecls(
2459
      R"(
2460
      template <typename T, T x>
2461
      class A;
2462
      template <typename T, T x, T y>
2463
      void foo(A<T, x>);
2464
      )",
2465
      R"(
2466
      template <typename T, T x>
2467
      class A;
2468
      template <typename T, T x, T y>
2469
      void foo(A<T, y>);
2470
      )",
2471
      Lang_CXX11);
2472
  EXPECT_FALSE(testStructuralMatch(t));
2473
}
2474

2475
TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) {
2476
  auto t = makeStmts(
2477
      R"(
2478
      void f1(int);
2479
      template <typename T>
2480
      void f(T t) {
2481
        f1(t);
2482
      }
2483
      void g() { f<int>(1); }
2484
      )",
2485
      R"(
2486
      void f2(int);
2487
      template <typename T>
2488
      void f(T t) {
2489
        f2(t);
2490
      }
2491
      void g() { f<int>(1); }
2492
      )",
2493
      Lang_CXX03, unresolvedLookupExpr());
2494
  EXPECT_FALSE(testStructuralMatch(t));
2495
}
2496

2497
TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentQualifier) {
2498
  auto t = makeStmts(
2499
      R"(
2500
      struct X {
2501
        static void g(int);
2502
        static void g(char);
2503
      };
2504

2505
      template <typename T>
2506
      void f(T t) {
2507
        X::g(t);
2508
      }
2509

2510
      void g() { f<int>(1); }
2511
      )",
2512
      R"(
2513
      struct Y {
2514
        static void g(int);
2515
        static void g(char);
2516
      };
2517

2518
      template <typename T>
2519
      void f(T t) {
2520
        Y::g(t);
2521
      }
2522

2523
      void g() { f<int>(1); }
2524
      )",
2525
      Lang_CXX03, unresolvedLookupExpr());
2526
  EXPECT_FALSE(testStructuralMatch(t));
2527
}
2528

2529
TEST_F(StructuralEquivalenceStmtTest,
2530
       UnresolvedLookupDifferentTemplateArgument) {
2531
  auto t = makeStmts(
2532
      R"(
2533
      struct A {};
2534
      template<typename T1, typename T2>
2535
      void g() {}
2536

2537
      template <typename T>
2538
      void f() {
2539
        g<A, T>();
2540
      }
2541

2542
      void h() { f<int>(); }
2543
      )",
2544
      R"(
2545
      struct B {};
2546
      template<typename T1, typename T2>
2547
      void g() {}
2548

2549
      template <typename T>
2550
      void f() {
2551
        g<B, T>();
2552
      }
2553

2554
      void h() { f<int>(); }
2555
      )",
2556
      Lang_CXX03, unresolvedLookupExpr());
2557
  EXPECT_FALSE(testStructuralMatch(t));
2558
}
2559

2560
TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) {
2561
  auto t = makeStmts(
2562
      R"(
2563
      struct A {};
2564
      struct B {
2565
        template<typename T1, typename T2>
2566
        static void g(int) {};
2567
        template<typename T1, typename T2>
2568
        static void g(char) {};
2569
      };
2570

2571
      template <typename T1, typename T2>
2572
      void f(T2 x) {
2573
        B::g<A, T1>(x);
2574
      }
2575

2576
      void g() { f<char, int>(1); }
2577
      )",
2578
      R"(
2579
      struct A {};
2580
      struct B {
2581
        template<typename T1, typename T2>
2582
        static void g(int) {};
2583
        template<typename T1, typename T2>
2584
        static void g(char) {};
2585
      };
2586

2587
      template <typename T1, typename T2>
2588
      void f(T2 x) {
2589
        B::g<A, T1>(x);
2590
      }
2591

2592
      void g() { f<char, int>(1); }
2593
      )",
2594
      Lang_CXX03, unresolvedLookupExpr());
2595
  EXPECT_TRUE(testStructuralMatch(t));
2596
}
2597

2598
TEST_F(StructuralEquivalenceCacheTest, GotoStmtNoEq) {
2599
  auto S = makeStmts(
2600
      R"(
2601
      void foo() {
2602
        goto L1;
2603
        L1: foo();
2604
      }
2605
      )",
2606
      R"(
2607
      void foo() {
2608
        goto L2;
2609
        L2: foo();
2610
      }
2611
      )",
2612
      Lang_CXX03, gotoStmt());
2613
  EXPECT_FALSE(testStructuralMatch(S));
2614
}
2615

2616
TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) {
2617
  std::string Prefix = "enum Test { AAA, BBB };";
2618
  auto t = makeStmts(
2619
      Prefix + "void foo(int i) {if (i > 0) {i = AAA;} else {i = BBB;}}",
2620
      Prefix + "void foo(int i) {if (i > 0) {i = BBB;} else {i = AAA;}}",
2621
      Lang_CXX03, ifStmt());
2622
  EXPECT_FALSE(testStructuralMatch(t));
2623
}
2624

2625
TEST_F(StructuralEquivalenceCacheTest, CXXDependentScopeMemberExprNoEq) {
2626
  auto S = makeStmts(
2627
      R"(
2628
      template <class T>
2629
      void foo() {
2630
        (void)T().x;
2631
      }
2632
      struct A { int x; };
2633
      void bar() {
2634
        foo<A>();
2635
      }
2636
      )",
2637
      R"(
2638
      template <class T>
2639
      void foo() {
2640
        (void)T().y;
2641
      }
2642
      struct A { int y; };
2643
      void bar() {
2644
        foo<A>();
2645
      }
2646
      )",
2647
      Lang_CXX11, cxxDependentScopeMemberExpr());
2648
  EXPECT_FALSE(testStructuralMatch(S));
2649
}
2650

2651
} // end namespace ast_matchers
2652
} // end namespace clang
2653

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.