StructuralEquivalenceTest.cpp 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
  1. #include "clang/AST/ASTContext.h"
  2. #include "clang/ASTMatchers/ASTMatchers.h"
  3. #include "clang/AST/ASTStructuralEquivalence.h"
  4. #include "clang/Frontend/ASTUnit.h"
  5. #include "clang/Tooling/Tooling.h"
  6. #include "Language.h"
  7. #include "DeclMatcher.h"
  8. #include "gtest/gtest.h"
  9. namespace clang {
  10. namespace ast_matchers {
  11. using std::get;
  12. struct StructuralEquivalenceTest : ::testing::Test {
  13. std::unique_ptr<ASTUnit> AST0, AST1;
  14. std::string Code0, Code1; // Buffers for SourceManager
  15. // Get a pair of node pointers into the synthesized AST from the given code
  16. // snippets. To determine the returned node, a separate matcher is specified
  17. // for both snippets. The first matching node is returned.
  18. template <typename NodeType, typename MatcherType>
  19. std::tuple<NodeType *, NodeType *> makeDecls(
  20. const std::string &SrcCode0, const std::string &SrcCode1, Language Lang,
  21. const MatcherType &Matcher0, const MatcherType &Matcher1) {
  22. this->Code0 = SrcCode0;
  23. this->Code1 = SrcCode1;
  24. ArgVector Args = getBasicRunOptionsForLanguage(Lang);
  25. const char *const InputFileName = "input.cc";
  26. AST0 = tooling::buildASTFromCodeWithArgs(Code0, Args, InputFileName);
  27. AST1 = tooling::buildASTFromCodeWithArgs(Code1, Args, InputFileName);
  28. NodeType *D0 = FirstDeclMatcher<NodeType>().match(
  29. AST0->getASTContext().getTranslationUnitDecl(), Matcher0);
  30. NodeType *D1 = FirstDeclMatcher<NodeType>().match(
  31. AST1->getASTContext().getTranslationUnitDecl(), Matcher1);
  32. return std::make_tuple(D0, D1);
  33. }
  34. std::tuple<TranslationUnitDecl *, TranslationUnitDecl *> makeTuDecls(
  35. const std::string &SrcCode0, const std::string &SrcCode1, Language Lang) {
  36. this->Code0 = SrcCode0;
  37. this->Code1 = SrcCode1;
  38. ArgVector Args = getBasicRunOptionsForLanguage(Lang);
  39. const char *const InputFileName = "input.cc";
  40. AST0 = tooling::buildASTFromCodeWithArgs(Code0, Args, InputFileName);
  41. AST1 = tooling::buildASTFromCodeWithArgs(Code1, Args, InputFileName);
  42. return std::make_tuple(AST0->getASTContext().getTranslationUnitDecl(),
  43. AST1->getASTContext().getTranslationUnitDecl());
  44. }
  45. // Get a pair of node pointers into the synthesized AST from the given code
  46. // snippets. The same matcher is used for both snippets.
  47. template <typename NodeType, typename MatcherType>
  48. std::tuple<NodeType *, NodeType *> makeDecls(
  49. const std::string &SrcCode0, const std::string &SrcCode1, Language Lang,
  50. const MatcherType &AMatcher) {
  51. return makeDecls<NodeType, MatcherType>(
  52. SrcCode0, SrcCode1, Lang, AMatcher, AMatcher);
  53. }
  54. // Get a pair of Decl pointers to the synthesized declarations from the given
  55. // code snippets. We search for the first NamedDecl with given name in both
  56. // snippets.
  57. std::tuple<NamedDecl *, NamedDecl *> makeNamedDecls(
  58. const std::string &SrcCode0, const std::string &SrcCode1,
  59. Language Lang, const char *const Identifier = "foo") {
  60. auto Matcher = namedDecl(hasName(Identifier));
  61. return makeDecls<NamedDecl>(SrcCode0, SrcCode1, Lang, Matcher);
  62. }
  63. bool testStructuralMatch(Decl *D0, Decl *D1) {
  64. llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls01;
  65. llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls10;
  66. StructuralEquivalenceContext Ctx01(
  67. D0->getASTContext(), D1->getASTContext(),
  68. NonEquivalentDecls01, StructuralEquivalenceKind::Default, false, false);
  69. StructuralEquivalenceContext Ctx10(
  70. D1->getASTContext(), D0->getASTContext(),
  71. NonEquivalentDecls10, StructuralEquivalenceKind::Default, false, false);
  72. bool Eq01 = Ctx01.IsEquivalent(D0, D1);
  73. bool Eq10 = Ctx10.IsEquivalent(D1, D0);
  74. EXPECT_EQ(Eq01, Eq10);
  75. return Eq01;
  76. }
  77. bool testStructuralMatch(std::tuple<Decl *, Decl *> t) {
  78. return testStructuralMatch(get<0>(t), get<1>(t));
  79. }
  80. };
  81. TEST_F(StructuralEquivalenceTest, Int) {
  82. auto Decls = makeNamedDecls("int foo;", "int foo;", Lang_CXX);
  83. EXPECT_TRUE(testStructuralMatch(Decls));
  84. }
  85. TEST_F(StructuralEquivalenceTest, IntVsSignedInt) {
  86. auto Decls = makeNamedDecls("int foo;", "signed int foo;", Lang_CXX);
  87. EXPECT_TRUE(testStructuralMatch(Decls));
  88. }
  89. TEST_F(StructuralEquivalenceTest, Char) {
  90. auto Decls = makeNamedDecls("char foo;", "char foo;", Lang_CXX);
  91. EXPECT_TRUE(testStructuralMatch(Decls));
  92. }
  93. // This test is disabled for now.
  94. // FIXME Whether this is equivalent is dependendant on the target.
  95. TEST_F(StructuralEquivalenceTest, DISABLED_CharVsSignedChar) {
  96. auto Decls = makeNamedDecls("char foo;", "signed char foo;", Lang_CXX);
  97. EXPECT_FALSE(testStructuralMatch(Decls));
  98. }
  99. TEST_F(StructuralEquivalenceTest, ForwardRecordDecl) {
  100. auto Decls = makeNamedDecls("struct foo;", "struct foo;", Lang_CXX);
  101. EXPECT_TRUE(testStructuralMatch(Decls));
  102. }
  103. TEST_F(StructuralEquivalenceTest, IntVsSignedIntInStruct) {
  104. auto Decls = makeNamedDecls("struct foo { int x; };",
  105. "struct foo { signed int x; };", Lang_CXX);
  106. EXPECT_TRUE(testStructuralMatch(Decls));
  107. }
  108. TEST_F(StructuralEquivalenceTest, CharVsSignedCharInStruct) {
  109. auto Decls = makeNamedDecls("struct foo { char x; };",
  110. "struct foo { signed char x; };", Lang_CXX);
  111. EXPECT_FALSE(testStructuralMatch(Decls));
  112. }
  113. TEST_F(StructuralEquivalenceTest, IntVsSignedIntTemplateSpec) {
  114. auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
  115. R"(template <class T> struct foo; template<> struct foo<int>{};)",
  116. R"(template <class T> struct foo; template<> struct foo<signed int>{};)",
  117. Lang_CXX,
  118. classTemplateSpecializationDecl());
  119. auto Spec0 = get<0>(Decls);
  120. auto Spec1 = get<1>(Decls);
  121. EXPECT_TRUE(testStructuralMatch(Spec0, Spec1));
  122. }
  123. TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpec) {
  124. auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
  125. R"(template <class T> struct foo; template<> struct foo<char>{};)",
  126. R"(template <class T> struct foo; template<> struct foo<signed char>{};)",
  127. Lang_CXX,
  128. classTemplateSpecializationDecl());
  129. auto Spec0 = get<0>(Decls);
  130. auto Spec1 = get<1>(Decls);
  131. EXPECT_FALSE(testStructuralMatch(Spec0, Spec1));
  132. }
  133. TEST_F(StructuralEquivalenceTest, CharVsSignedCharTemplateSpecWithInheritance) {
  134. auto Decls = makeDecls<ClassTemplateSpecializationDecl>(
  135. R"(
  136. struct true_type{};
  137. template <class T> struct foo;
  138. template<> struct foo<char> : true_type {};
  139. )",
  140. R"(
  141. struct true_type{};
  142. template <class T> struct foo;
  143. template<> struct foo<signed char> : true_type {};
  144. )",
  145. Lang_CXX,
  146. classTemplateSpecializationDecl());
  147. EXPECT_FALSE(testStructuralMatch(Decls));
  148. }
  149. // This test is disabled for now.
  150. // FIXME Enable it, once the check is implemented.
  151. TEST_F(StructuralEquivalenceTest, DISABLED_WrongOrderInNamespace) {
  152. auto Code =
  153. R"(
  154. namespace NS {
  155. template <class T> class Base {
  156. int a;
  157. };
  158. class Derived : Base<Derived> {
  159. };
  160. }
  161. void foo(NS::Derived &);
  162. )";
  163. auto Decls = makeNamedDecls(Code, Code, Lang_CXX);
  164. NamespaceDecl *NS =
  165. LastDeclMatcher<NamespaceDecl>().match(get<1>(Decls), namespaceDecl());
  166. ClassTemplateDecl *TD = LastDeclMatcher<ClassTemplateDecl>().match(
  167. get<1>(Decls), classTemplateDecl(hasName("Base")));
  168. // Reorder the decls, move the TD to the last place in the DC.
  169. NS->removeDecl(TD);
  170. NS->addDeclInternal(TD);
  171. EXPECT_FALSE(testStructuralMatch(Decls));
  172. }
  173. TEST_F(StructuralEquivalenceTest, WrongOrderOfFieldsInClass) {
  174. auto Code = "class X { int a; int b; };";
  175. auto Decls = makeNamedDecls(Code, Code, Lang_CXX, "X");
  176. CXXRecordDecl *RD = FirstDeclMatcher<CXXRecordDecl>().match(
  177. get<1>(Decls), cxxRecordDecl(hasName("X")));
  178. FieldDecl *FD =
  179. FirstDeclMatcher<FieldDecl>().match(get<1>(Decls), fieldDecl(hasName("a")));
  180. // Reorder the FieldDecls
  181. RD->removeDecl(FD);
  182. RD->addDeclInternal(FD);
  183. EXPECT_FALSE(testStructuralMatch(Decls));
  184. }
  185. struct StructuralEquivalenceFunctionTest : StructuralEquivalenceTest {
  186. };
  187. TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) {
  188. auto t = makeNamedDecls(
  189. "void foo();",
  190. "template<class T> void foo();",
  191. Lang_CXX);
  192. EXPECT_FALSE(testStructuralMatch(t));
  193. }
  194. TEST_F(StructuralEquivalenceFunctionTest, DifferentOperators) {
  195. auto t = makeDecls<FunctionDecl>(
  196. "struct X{}; bool operator<(X, X);",
  197. "struct X{}; bool operator==(X, X);", Lang_CXX,
  198. functionDecl(hasOverloadedOperatorName("<")),
  199. functionDecl(hasOverloadedOperatorName("==")));
  200. EXPECT_FALSE(testStructuralMatch(t));
  201. }
  202. TEST_F(StructuralEquivalenceFunctionTest, SameOperators) {
  203. auto t = makeDecls<FunctionDecl>(
  204. "struct X{}; bool operator<(X, X);",
  205. "struct X{}; bool operator<(X, X);", Lang_CXX,
  206. functionDecl(hasOverloadedOperatorName("<")),
  207. functionDecl(hasOverloadedOperatorName("<")));
  208. EXPECT_TRUE(testStructuralMatch(t));
  209. }
  210. TEST_F(StructuralEquivalenceFunctionTest, CtorVsDtor) {
  211. auto t = makeDecls<FunctionDecl>(
  212. "struct X{ X(); };",
  213. "struct X{ ~X(); };", Lang_CXX,
  214. cxxConstructorDecl(),
  215. cxxDestructorDecl());
  216. EXPECT_FALSE(testStructuralMatch(t));
  217. }
  218. TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) {
  219. auto t = makeNamedDecls("void foo(int&);",
  220. "void foo(const int&);", Lang_CXX);
  221. EXPECT_FALSE(testStructuralMatch(t));
  222. }
  223. TEST_F(StructuralEquivalenceFunctionTest, ParamConstSimple) {
  224. auto t = makeNamedDecls("void foo(int);",
  225. "void foo(const int);", Lang_CXX);
  226. EXPECT_TRUE(testStructuralMatch(t));
  227. // consider this OK
  228. }
  229. TEST_F(StructuralEquivalenceFunctionTest, Throw) {
  230. auto t = makeNamedDecls("void foo();",
  231. "void foo() throw();", Lang_CXX);
  232. EXPECT_FALSE(testStructuralMatch(t));
  233. }
  234. TEST_F(StructuralEquivalenceFunctionTest, Noexcept) {
  235. auto t = makeNamedDecls("void foo();",
  236. "void foo() noexcept;", Lang_CXX11);
  237. EXPECT_FALSE(testStructuralMatch(t));
  238. }
  239. TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexcept) {
  240. auto t = makeNamedDecls("void foo() throw();",
  241. "void foo() noexcept;", Lang_CXX11);
  242. EXPECT_FALSE(testStructuralMatch(t));
  243. }
  244. TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptFalse) {
  245. auto t = makeNamedDecls("void foo() throw();",
  246. "void foo() noexcept(false);", Lang_CXX11);
  247. EXPECT_FALSE(testStructuralMatch(t));
  248. }
  249. TEST_F(StructuralEquivalenceFunctionTest, ThrowVsNoexceptTrue) {
  250. auto t = makeNamedDecls("void foo() throw();",
  251. "void foo() noexcept(true);", Lang_CXX11);
  252. EXPECT_FALSE(testStructuralMatch(t));
  253. }
  254. TEST_F(StructuralEquivalenceFunctionTest, NoexceptNonMatch) {
  255. auto t = makeNamedDecls("void foo() noexcept(false);",
  256. "void foo() noexcept(true);", Lang_CXX11);
  257. EXPECT_FALSE(testStructuralMatch(t));
  258. }
  259. TEST_F(StructuralEquivalenceFunctionTest, NoexceptMatch) {
  260. auto t = makeNamedDecls("void foo() noexcept(false);",
  261. "void foo() noexcept(false);", Lang_CXX11);
  262. EXPECT_TRUE(testStructuralMatch(t));
  263. }
  264. TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptFalse) {
  265. auto t = makeNamedDecls("void foo() noexcept;",
  266. "void foo() noexcept(false);", Lang_CXX11);
  267. EXPECT_FALSE(testStructuralMatch(t));
  268. }
  269. TEST_F(StructuralEquivalenceFunctionTest, NoexceptVsNoexceptTrue) {
  270. auto t = makeNamedDecls("void foo() noexcept;",
  271. "void foo() noexcept(true);", Lang_CXX11);
  272. EXPECT_FALSE(testStructuralMatch(t));
  273. }
  274. TEST_F(StructuralEquivalenceFunctionTest, ReturnType) {
  275. auto t = makeNamedDecls("char foo();",
  276. "int foo();", Lang_CXX);
  277. EXPECT_FALSE(testStructuralMatch(t));
  278. }
  279. TEST_F(StructuralEquivalenceFunctionTest, ReturnConst) {
  280. auto t = makeNamedDecls("char foo();",
  281. "const char foo();", Lang_CXX);
  282. EXPECT_FALSE(testStructuralMatch(t));
  283. }
  284. TEST_F(StructuralEquivalenceFunctionTest, ReturnRef) {
  285. auto t = makeNamedDecls("char &foo();",
  286. "char &&foo();", Lang_CXX11);
  287. EXPECT_FALSE(testStructuralMatch(t));
  288. }
  289. TEST_F(StructuralEquivalenceFunctionTest, ParamCount) {
  290. auto t = makeNamedDecls("void foo(int);",
  291. "void foo(int, int);", Lang_CXX);
  292. EXPECT_FALSE(testStructuralMatch(t));
  293. }
  294. TEST_F(StructuralEquivalenceFunctionTest, ParamType) {
  295. auto t = makeNamedDecls("void foo(int);",
  296. "void foo(char);", Lang_CXX);
  297. EXPECT_FALSE(testStructuralMatch(t));
  298. }
  299. TEST_F(StructuralEquivalenceFunctionTest, ParamName) {
  300. auto t = makeNamedDecls("void foo(int a);",
  301. "void foo(int b);", Lang_CXX);
  302. EXPECT_TRUE(testStructuralMatch(t));
  303. }
  304. TEST_F(StructuralEquivalenceFunctionTest, Variadic) {
  305. auto t = makeNamedDecls("void foo(int x...);",
  306. "void foo(int x);", Lang_CXX);
  307. EXPECT_FALSE(testStructuralMatch(t));
  308. }
  309. TEST_F(StructuralEquivalenceFunctionTest, ParamPtr) {
  310. auto t = makeNamedDecls("void foo(int *);",
  311. "void foo(int);", Lang_CXX);
  312. EXPECT_FALSE(testStructuralMatch(t));
  313. }
  314. TEST_F(StructuralEquivalenceFunctionTest, NameInParen) {
  315. auto t = makeNamedDecls(
  316. "void ((foo))();",
  317. "void foo();",
  318. Lang_CXX);
  319. EXPECT_TRUE(testStructuralMatch(t));
  320. }
  321. TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithExceptionSpec) {
  322. auto t = makeNamedDecls(
  323. "void (foo)() throw(int);",
  324. "void (foo)() noexcept;",
  325. Lang_CXX11);
  326. EXPECT_FALSE(testStructuralMatch(t));
  327. }
  328. TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithConst) {
  329. auto t = makeNamedDecls(
  330. "struct A { void (foo)() const; };",
  331. "struct A { void (foo)(); };",
  332. Lang_CXX11);
  333. EXPECT_FALSE(testStructuralMatch(t));
  334. }
  335. TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentNoreturnAttr) {
  336. auto t = makeNamedDecls(
  337. "__attribute__((noreturn)) void foo();",
  338. " void foo();",
  339. Lang_C);
  340. EXPECT_TRUE(testStructuralMatch(t));
  341. }
  342. TEST_F(StructuralEquivalenceFunctionTest,
  343. FunctionsWithDifferentCallingConventions) {
  344. // These attributes may not be available on certain platforms.
  345. if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
  346. llvm::Triple::x86_64)
  347. return;
  348. auto t = makeNamedDecls(
  349. "__attribute__((preserve_all)) void foo();",
  350. "__attribute__((ms_abi)) void foo();",
  351. Lang_C);
  352. EXPECT_FALSE(testStructuralMatch(t));
  353. }
  354. TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) {
  355. if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
  356. llvm::Triple::x86_64)
  357. return;
  358. auto t = makeNamedDecls(
  359. "__attribute__((no_caller_saved_registers)) void foo();",
  360. " void foo();",
  361. Lang_C);
  362. EXPECT_FALSE(testStructuralMatch(t));
  363. }
  364. struct StructuralEquivalenceCXXMethodTest : StructuralEquivalenceTest {
  365. };
  366. TEST_F(StructuralEquivalenceCXXMethodTest, Virtual) {
  367. auto t = makeDecls<CXXMethodDecl>(
  368. "struct X { void foo(); };",
  369. "struct X { virtual void foo(); };", Lang_CXX,
  370. cxxMethodDecl(hasName("foo")));
  371. EXPECT_FALSE(testStructuralMatch(t));
  372. }
  373. TEST_F(StructuralEquivalenceCXXMethodTest, Pure) {
  374. auto t = makeNamedDecls("struct X { virtual void foo(); };",
  375. "struct X { virtual void foo() = 0; };", Lang_CXX);
  376. EXPECT_FALSE(testStructuralMatch(t));
  377. }
  378. TEST_F(StructuralEquivalenceCXXMethodTest, DISABLED_Final) {
  379. // The final-ness is not checked yet.
  380. auto t = makeNamedDecls("struct X { virtual void foo(); };",
  381. "struct X { virtual void foo() final; };", Lang_CXX);
  382. EXPECT_FALSE(testStructuralMatch(t));
  383. }
  384. TEST_F(StructuralEquivalenceCXXMethodTest, Const) {
  385. auto t = makeNamedDecls("struct X { void foo(); };",
  386. "struct X { void foo() const; };", Lang_CXX);
  387. EXPECT_FALSE(testStructuralMatch(t));
  388. }
  389. TEST_F(StructuralEquivalenceCXXMethodTest, Static) {
  390. auto t = makeNamedDecls("struct X { void foo(); };",
  391. "struct X { static void foo(); };", Lang_CXX);
  392. EXPECT_FALSE(testStructuralMatch(t));
  393. }
  394. TEST_F(StructuralEquivalenceCXXMethodTest, Ref1) {
  395. auto t = makeNamedDecls("struct X { void foo(); };",
  396. "struct X { void foo() &&; };", Lang_CXX11);
  397. EXPECT_FALSE(testStructuralMatch(t));
  398. }
  399. TEST_F(StructuralEquivalenceCXXMethodTest, Ref2) {
  400. auto t = makeNamedDecls("struct X { void foo() &; };",
  401. "struct X { void foo() &&; };", Lang_CXX11);
  402. EXPECT_FALSE(testStructuralMatch(t));
  403. }
  404. TEST_F(StructuralEquivalenceCXXMethodTest, AccessSpecifier) {
  405. auto t = makeDecls<CXXMethodDecl>(
  406. "struct X { public: void foo(); };",
  407. "struct X { private: void foo(); };", Lang_CXX,
  408. cxxMethodDecl(hasName("foo")));
  409. EXPECT_FALSE(testStructuralMatch(t));
  410. }
  411. TEST_F(StructuralEquivalenceCXXMethodTest, Delete) {
  412. auto t = makeNamedDecls("struct X { void foo(); };",
  413. "struct X { void foo() = delete; };", Lang_CXX11);
  414. EXPECT_FALSE(testStructuralMatch(t));
  415. }
  416. TEST_F(StructuralEquivalenceCXXMethodTest, Constructor) {
  417. auto t = makeDecls<FunctionDecl>(
  418. "void foo();", "struct foo { foo(); };", Lang_CXX,
  419. functionDecl(hasName("foo")), cxxConstructorDecl(hasName("foo")));
  420. EXPECT_FALSE(testStructuralMatch(t));
  421. }
  422. TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorParam) {
  423. auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
  424. "struct X { X(int); };", Lang_CXX,
  425. cxxConstructorDecl(hasName("X")));
  426. EXPECT_FALSE(testStructuralMatch(t));
  427. }
  428. TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorExplicit) {
  429. auto t = makeDecls<CXXConstructorDecl>("struct X { X(int); };",
  430. "struct X { explicit X(int); };",
  431. Lang_CXX11,
  432. cxxConstructorDecl(hasName("X")));
  433. EXPECT_FALSE(testStructuralMatch(t));
  434. }
  435. TEST_F(StructuralEquivalenceCXXMethodTest, ConstructorDefault) {
  436. auto t = makeDecls<CXXConstructorDecl>("struct X { X(); };",
  437. "struct X { X() = default; };",
  438. Lang_CXX11,
  439. cxxConstructorDecl(hasName("X")));
  440. EXPECT_FALSE(testStructuralMatch(t));
  441. }
  442. TEST_F(StructuralEquivalenceCXXMethodTest, Conversion) {
  443. auto t = makeDecls<CXXConversionDecl>("struct X { operator bool(); };",
  444. "struct X { operator char(); };",
  445. Lang_CXX11,
  446. cxxConversionDecl());
  447. EXPECT_FALSE(testStructuralMatch(t));
  448. }
  449. TEST_F(StructuralEquivalenceCXXMethodTest, Operator) {
  450. auto t = makeDecls<FunctionDecl>(
  451. "struct X { int operator +(int); };",
  452. "struct X { int operator -(int); };", Lang_CXX,
  453. functionDecl(hasOverloadedOperatorName("+")),
  454. functionDecl(hasOverloadedOperatorName("-")));
  455. EXPECT_FALSE(testStructuralMatch(t));
  456. }
  457. TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass1) {
  458. auto t = makeDecls<FunctionDecl>(
  459. "struct X { virtual void f(); }; void X::f() { }",
  460. "struct X { virtual void f() { }; };",
  461. Lang_CXX,
  462. functionDecl(allOf(hasName("f"), isDefinition())));
  463. EXPECT_TRUE(testStructuralMatch(t));
  464. }
  465. TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass2) {
  466. auto t = makeDecls<FunctionDecl>(
  467. "struct X { virtual void f(); }; void X::f() { }",
  468. "struct X { void f(); }; void X::f() { }",
  469. Lang_CXX,
  470. functionDecl(allOf(hasName("f"), isDefinition())));
  471. EXPECT_FALSE(testStructuralMatch(t));
  472. }
  473. struct StructuralEquivalenceRecordTest : StructuralEquivalenceTest {
  474. // FIXME Use a common getRecordDecl with ASTImporterTest.cpp!
  475. RecordDecl *getRecordDecl(FieldDecl *FD) {
  476. auto *ET = cast<ElaboratedType>(FD->getType().getTypePtr());
  477. return cast<RecordType>(ET->getNamedType().getTypePtr())->getDecl();
  478. };
  479. };
  480. TEST_F(StructuralEquivalenceRecordTest, Name) {
  481. auto t = makeDecls<CXXRecordDecl>(
  482. "struct A{ };",
  483. "struct B{ };",
  484. Lang_CXX,
  485. cxxRecordDecl(hasName("A")),
  486. cxxRecordDecl(hasName("B")));
  487. EXPECT_FALSE(testStructuralMatch(t));
  488. }
  489. TEST_F(StructuralEquivalenceRecordTest, Fields) {
  490. auto t = makeNamedDecls(
  491. "struct foo{ int x; };",
  492. "struct foo{ char x; };",
  493. Lang_CXX);
  494. EXPECT_FALSE(testStructuralMatch(t));
  495. }
  496. TEST_F(StructuralEquivalenceRecordTest, DISABLED_Methods) {
  497. // Currently, methods of a class are not checked at class equivalence.
  498. auto t = makeNamedDecls(
  499. "struct foo{ int x(); };",
  500. "struct foo{ char x(); };",
  501. Lang_CXX);
  502. EXPECT_FALSE(testStructuralMatch(t));
  503. }
  504. TEST_F(StructuralEquivalenceRecordTest, Bases) {
  505. auto t = makeNamedDecls(
  506. "struct A{ }; struct foo: A { };",
  507. "struct B{ }; struct foo: B { };",
  508. Lang_CXX);
  509. EXPECT_FALSE(testStructuralMatch(t));
  510. }
  511. TEST_F(StructuralEquivalenceRecordTest, InheritanceVirtual) {
  512. auto t = makeNamedDecls(
  513. "struct A{ }; struct foo: A { };",
  514. "struct A{ }; struct foo: virtual A { };",
  515. Lang_CXX);
  516. EXPECT_FALSE(testStructuralMatch(t));
  517. }
  518. TEST_F(StructuralEquivalenceRecordTest, DISABLED_InheritanceType) {
  519. // Access specifier in inheritance is not checked yet.
  520. auto t = makeNamedDecls(
  521. "struct A{ }; struct foo: public A { };",
  522. "struct A{ }; struct foo: private A { };",
  523. Lang_CXX);
  524. EXPECT_FALSE(testStructuralMatch(t));
  525. }
  526. TEST_F(StructuralEquivalenceRecordTest, Match) {
  527. auto Code = R"(
  528. struct A{ };
  529. struct B{ };
  530. struct foo: A, virtual B {
  531. void x();
  532. int a;
  533. };
  534. )";
  535. auto t = makeNamedDecls(Code, Code, Lang_CXX);
  536. EXPECT_TRUE(testStructuralMatch(t));
  537. }
  538. TEST_F(StructuralEquivalenceRecordTest, UnnamedRecordsShouldBeInequivalent) {
  539. auto t = makeTuDecls(
  540. R"(
  541. struct A {
  542. struct {
  543. struct A *next;
  544. } entry0;
  545. struct {
  546. struct A *next;
  547. } entry1;
  548. };
  549. )",
  550. "", Lang_C);
  551. auto *TU = get<0>(t);
  552. auto *Entry0 =
  553. FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry0")));
  554. auto *Entry1 =
  555. FirstDeclMatcher<FieldDecl>().match(TU, fieldDecl(hasName("entry1")));
  556. auto *R0 = getRecordDecl(Entry0);
  557. auto *R1 = getRecordDecl(Entry1);
  558. ASSERT_NE(R0, R1);
  559. EXPECT_TRUE(testStructuralMatch(R0, R0));
  560. EXPECT_TRUE(testStructuralMatch(R1, R1));
  561. EXPECT_FALSE(testStructuralMatch(R0, R1));
  562. }
  563. TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) {
  564. auto t = makeTuDecls(
  565. R"(
  566. struct X {
  567. struct {
  568. int a;
  569. };
  570. struct {
  571. int b;
  572. };
  573. };
  574. )",
  575. "", Lang_C);
  576. auto *TU = get<0>(t);
  577. auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
  578. TU, indirectFieldDecl(hasName("a")));
  579. auto *FA = cast<FieldDecl>(A->chain().front());
  580. RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
  581. auto *B = FirstDeclMatcher<IndirectFieldDecl>().match(
  582. TU, indirectFieldDecl(hasName("b")));
  583. auto *FB = cast<FieldDecl>(B->chain().front());
  584. RecordDecl *RB = cast<RecordType>(FB->getType().getTypePtr())->getDecl();
  585. ASSERT_NE(RA, RB);
  586. EXPECT_TRUE(testStructuralMatch(RA, RA));
  587. EXPECT_TRUE(testStructuralMatch(RB, RB));
  588. EXPECT_FALSE(testStructuralMatch(RA, RB));
  589. }
  590. TEST_F(StructuralEquivalenceRecordTest,
  591. RecordsAreInequivalentIfOrderOfAnonRecordsIsDifferent) {
  592. auto t = makeTuDecls(
  593. R"(
  594. struct X {
  595. struct { int a; };
  596. struct { int b; };
  597. };
  598. )",
  599. R"(
  600. struct X { // The order is reversed.
  601. struct { int b; };
  602. struct { int a; };
  603. };
  604. )",
  605. Lang_C);
  606. auto *TU = get<0>(t);
  607. auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
  608. TU, indirectFieldDecl(hasName("a")));
  609. auto *FA = cast<FieldDecl>(A->chain().front());
  610. RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
  611. auto *TU1 = get<1>(t);
  612. auto *A1 = FirstDeclMatcher<IndirectFieldDecl>().match(
  613. TU1, indirectFieldDecl(hasName("a")));
  614. auto *FA1 = cast<FieldDecl>(A1->chain().front());
  615. RecordDecl *RA1 = cast<RecordType>(FA1->getType().getTypePtr())->getDecl();
  616. RecordDecl *X =
  617. FirstDeclMatcher<RecordDecl>().match(TU, recordDecl(hasName("X")));
  618. RecordDecl *X1 =
  619. FirstDeclMatcher<RecordDecl>().match(TU1, recordDecl(hasName("X")));
  620. ASSERT_NE(X, X1);
  621. EXPECT_FALSE(testStructuralMatch(X, X1));
  622. ASSERT_NE(RA, RA1);
  623. EXPECT_TRUE(testStructuralMatch(RA, RA));
  624. EXPECT_TRUE(testStructuralMatch(RA1, RA1));
  625. EXPECT_FALSE(testStructuralMatch(RA1, RA));
  626. }
  627. TEST_F(StructuralEquivalenceRecordTest,
  628. UnnamedRecordsShouldBeInequivalentEvenIfTheSecondIsBeingDefined) {
  629. auto Code =
  630. R"(
  631. struct A {
  632. struct {
  633. struct A *next;
  634. } entry0;
  635. struct {
  636. struct A *next;
  637. } entry1;
  638. };
  639. )";
  640. auto t = makeTuDecls(Code, Code, Lang_C);
  641. auto *FromTU = get<0>(t);
  642. auto *Entry1 =
  643. FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("entry1")));
  644. auto *ToTU = get<1>(t);
  645. auto *Entry0 =
  646. FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0")));
  647. auto *A =
  648. FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
  649. A->startDefinition(); // Set isBeingDefined, getDefinition() will return a
  650. // nullptr. This may be the case during ASTImport.
  651. auto *R0 = getRecordDecl(Entry0);
  652. auto *R1 = getRecordDecl(Entry1);
  653. ASSERT_NE(R0, R1);
  654. EXPECT_TRUE(testStructuralMatch(R0, R0));
  655. EXPECT_TRUE(testStructuralMatch(R1, R1));
  656. EXPECT_FALSE(testStructuralMatch(R0, R1));
  657. }
  658. TEST_F(StructuralEquivalenceRecordTest, TemplateVsNonTemplate) {
  659. auto t = makeDecls<CXXRecordDecl>(
  660. "struct A { };",
  661. "template<class T> struct A { };",
  662. Lang_CXX,
  663. cxxRecordDecl(hasName("A")));
  664. EXPECT_FALSE(testStructuralMatch(t));
  665. }
  666. TEST_F(StructuralEquivalenceRecordTest,
  667. FwdDeclRecordShouldBeEqualWithFwdDeclRecord) {
  668. auto t = makeNamedDecls("class foo;", "class foo;", Lang_CXX11);
  669. EXPECT_TRUE(testStructuralMatch(t));
  670. }
  671. TEST_F(StructuralEquivalenceRecordTest,
  672. FwdDeclRecordShouldBeEqualWithRecordWhichHasDefinition) {
  673. auto t =
  674. makeNamedDecls("class foo;", "class foo { int A; };", Lang_CXX11);
  675. EXPECT_TRUE(testStructuralMatch(t));
  676. }
  677. TEST_F(StructuralEquivalenceRecordTest,
  678. RecordShouldBeEqualWithRecordWhichHasDefinition) {
  679. auto t = makeNamedDecls("class foo { int A; };", "class foo { int A; };",
  680. Lang_CXX11);
  681. EXPECT_TRUE(testStructuralMatch(t));
  682. }
  683. TEST_F(StructuralEquivalenceRecordTest, RecordsWithDifferentBody) {
  684. auto t = makeNamedDecls("class foo { int B; };", "class foo { int A; };",
  685. Lang_CXX11);
  686. EXPECT_FALSE(testStructuralMatch(t));
  687. }
  688. struct StructuralEquivalenceLambdaTest : StructuralEquivalenceTest {};
  689. TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentMethods) {
  690. // Get the LambdaExprs, unfortunately we can't match directly the underlying
  691. // implicit CXXRecordDecl of the Lambda classes.
  692. auto t = makeDecls<LambdaExpr>(
  693. "void f() { auto L0 = [](int){}; }",
  694. "void f() { auto L1 = [](){}; }",
  695. Lang_CXX11,
  696. lambdaExpr(),
  697. lambdaExpr());
  698. CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
  699. CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
  700. EXPECT_FALSE(testStructuralMatch(L0, L1));
  701. }
  702. TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqMethods) {
  703. auto t = makeDecls<LambdaExpr>(
  704. "void f() { auto L0 = [](int){}; }",
  705. "void f() { auto L1 = [](int){}; }",
  706. Lang_CXX11,
  707. lambdaExpr(),
  708. lambdaExpr());
  709. CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
  710. CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
  711. EXPECT_TRUE(testStructuralMatch(L0, L1));
  712. }
  713. TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentFields) {
  714. auto t = makeDecls<LambdaExpr>(
  715. "void f() { char* X; auto L0 = [X](){}; }",
  716. "void f() { float X; auto L1 = [X](){}; }",
  717. Lang_CXX11,
  718. lambdaExpr(),
  719. lambdaExpr());
  720. CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
  721. CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
  722. EXPECT_FALSE(testStructuralMatch(L0, L1));
  723. }
  724. TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqFields) {
  725. auto t = makeDecls<LambdaExpr>(
  726. "void f() { float X; auto L0 = [X](){}; }",
  727. "void f() { float X; auto L1 = [X](){}; }",
  728. Lang_CXX11,
  729. lambdaExpr(),
  730. lambdaExpr());
  731. CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
  732. CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
  733. EXPECT_TRUE(testStructuralMatch(L0, L1));
  734. }
  735. TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) {
  736. auto t = makeNamedDecls(
  737. "struct A{ }; struct B{ }; void foo(A a, A b);",
  738. "struct A{ }; struct B{ }; void foo(A a, B b);",
  739. Lang_CXX);
  740. EXPECT_FALSE(testStructuralMatch(t));
  741. }
  742. TEST_F(StructuralEquivalenceTest, ExplicitBoolDifferent) {
  743. auto Decls = makeNamedDecls("struct foo {explicit(false) foo(int);};",
  744. "struct foo {explicit(true) foo(int);};", Lang_CXX2a);
  745. CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
  746. get<0>(Decls), cxxConstructorDecl(hasName("foo")));
  747. CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
  748. get<1>(Decls), cxxConstructorDecl(hasName("foo")));
  749. EXPECT_FALSE(testStructuralMatch(First, Second));
  750. }
  751. TEST_F(StructuralEquivalenceTest, ExplicitBoolSame) {
  752. auto Decls = makeNamedDecls("struct foo {explicit(true) foo(int);};",
  753. "struct foo {explicit(true) foo(int);};", Lang_CXX2a);
  754. CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
  755. get<0>(Decls), cxxConstructorDecl(hasName("foo")));
  756. CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
  757. get<1>(Decls), cxxConstructorDecl(hasName("foo")));
  758. EXPECT_TRUE(testStructuralMatch(First, Second));
  759. }
  760. struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
  761. TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) {
  762. auto t = makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11);
  763. EXPECT_TRUE(testStructuralMatch(t));
  764. }
  765. TEST_F(StructuralEquivalenceEnumTest,
  766. FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition) {
  767. auto t =
  768. makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11);
  769. EXPECT_TRUE(testStructuralMatch(t));
  770. }
  771. TEST_F(StructuralEquivalenceEnumTest,
  772. EnumShouldBeEqualWithEnumWhichHasDefinition) {
  773. auto t = makeNamedDecls("enum class foo { A };", "enum class foo { A };",
  774. Lang_CXX11);
  775. EXPECT_TRUE(testStructuralMatch(t));
  776. }
  777. TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) {
  778. auto t = makeNamedDecls("enum class foo { B };", "enum class foo { A };",
  779. Lang_CXX11);
  780. EXPECT_FALSE(testStructuralMatch(t));
  781. }
  782. struct StructuralEquivalenceTemplateTest : StructuralEquivalenceTest {};
  783. TEST_F(StructuralEquivalenceTemplateTest, ExactlySameTemplates) {
  784. auto t = makeNamedDecls("template <class T> struct foo;",
  785. "template <class T> struct foo;", Lang_CXX);
  786. EXPECT_TRUE(testStructuralMatch(t));
  787. }
  788. TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgName) {
  789. auto t = makeNamedDecls("template <class T> struct foo;",
  790. "template <class U> struct foo;", Lang_CXX);
  791. EXPECT_TRUE(testStructuralMatch(t));
  792. }
  793. TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) {
  794. auto t = makeNamedDecls("template <class T> struct foo;",
  795. "template <int T> struct foo;", Lang_CXX);
  796. EXPECT_FALSE(testStructuralMatch(t));
  797. }
  798. TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) {
  799. auto Decls = makeNamedDecls("template <bool b> struct foo {explicit(b) foo(int);};",
  800. "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX2a);
  801. CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
  802. get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
  803. CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
  804. get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
  805. EXPECT_TRUE(testStructuralMatch(First, Second));
  806. }
  807. TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolDifference) {
  808. auto Decls = makeNamedDecls("template <bool b> struct foo {explicit(b) foo(int);};",
  809. "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX2a);
  810. CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
  811. get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
  812. CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
  813. get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
  814. EXPECT_FALSE(testStructuralMatch(First, Second));
  815. }
  816. TEST_F(StructuralEquivalenceTemplateTest,
  817. TemplateVsSubstTemplateTemplateParmInArgEq) {
  818. auto t = makeDecls<ClassTemplateSpecializationDecl>(
  819. R"(
  820. template <typename P1> class Arg { };
  821. template <template <typename PP1> class P1> class Primary { };
  822. void f() {
  823. // Make specialization with simple template.
  824. Primary <Arg> A;
  825. }
  826. )",
  827. R"(
  828. template <typename P1> class Arg { };
  829. template <template <typename PP1> class P1> class Primary { };
  830. template <template <typename PP1> class P1> class Templ {
  831. void f() {
  832. // Make specialization with substituted template template param.
  833. Primary <P1> A;
  834. };
  835. };
  836. // Instantiate with substitution Arg into P1.
  837. template class Templ <Arg>;
  838. )",
  839. Lang_CXX, classTemplateSpecializationDecl(hasName("Primary")));
  840. EXPECT_TRUE(testStructuralMatch(t));
  841. }
  842. TEST_F(StructuralEquivalenceTemplateTest,
  843. TemplateVsSubstTemplateTemplateParmInArgNotEq) {
  844. auto t = makeDecls<ClassTemplateSpecializationDecl>(
  845. R"(
  846. template <typename P1> class Arg { };
  847. template <template <typename PP1> class P1> class Primary { };
  848. void f() {
  849. // Make specialization with simple template.
  850. Primary <Arg> A;
  851. }
  852. )",
  853. R"(
  854. // Arg is different from the other, this should cause non-equivalence.
  855. template <typename P1> class Arg { int X; };
  856. template <template <typename PP1> class P1> class Primary { };
  857. template <template <typename PP1> class P1> class Templ {
  858. void f() {
  859. // Make specialization with substituted template template param.
  860. Primary <P1> A;
  861. };
  862. };
  863. // Instantiate with substitution Arg into P1.
  864. template class Templ <Arg>;
  865. )",
  866. Lang_CXX, classTemplateSpecializationDecl(hasName("Primary")));
  867. EXPECT_FALSE(testStructuralMatch(t));
  868. }
  869. struct StructuralEquivalenceDependentTemplateArgsTest
  870. : StructuralEquivalenceTemplateTest {};
  871. TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
  872. SameStructsInDependentArgs) {
  873. std::string Code =
  874. R"(
  875. template <typename>
  876. struct S1;
  877. template <typename>
  878. struct enable_if;
  879. struct S
  880. {
  881. template <typename T, typename enable_if<S1<T>>::type>
  882. void f();
  883. };
  884. )";
  885. auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
  886. functionTemplateDecl(hasName("f")));
  887. EXPECT_TRUE(testStructuralMatch(t));
  888. }
  889. TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
  890. DifferentStructsInDependentArgs) {
  891. std::string Code =
  892. R"(
  893. template <typename>
  894. struct S1;
  895. template <typename>
  896. struct S2;
  897. template <typename>
  898. struct enable_if;
  899. )";
  900. auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
  901. struct S
  902. {
  903. template <typename T, typename enable_if<S1<T>>::type>
  904. void f();
  905. };
  906. )",
  907. Code + R"(
  908. struct S
  909. {
  910. template <typename T, typename enable_if<S2<T>>::type>
  911. void f();
  912. };
  913. )",
  914. Lang_CXX11,
  915. functionTemplateDecl(hasName("f")));
  916. EXPECT_FALSE(testStructuralMatch(t));
  917. }
  918. TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
  919. SameStructsInDependentScopeDeclRefExpr) {
  920. std::string Code =
  921. R"(
  922. template <typename>
  923. struct S1;
  924. template <bool>
  925. struct enable_if;
  926. struct S
  927. {
  928. template <typename T, typename enable_if<S1<T>::value>::type>
  929. void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
  930. };
  931. )";
  932. auto t = makeDecls<FunctionTemplateDecl>(Code, Code, Lang_CXX11,
  933. functionTemplateDecl(hasName("f")));
  934. EXPECT_TRUE(testStructuralMatch(t));
  935. }
  936. TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
  937. DifferentStructsInDependentScopeDeclRefExpr) {
  938. std::string Code =
  939. R"(
  940. template <typename>
  941. struct S1;
  942. template <typename>
  943. struct S2;
  944. template <bool>
  945. struct enable_if;
  946. )";
  947. auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
  948. struct S
  949. {
  950. template <typename T, typename enable_if<S1<T>::value>::type>
  951. void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
  952. };
  953. )",
  954. Code + R"(
  955. struct S
  956. {
  957. template <typename T, typename enable_if<S2<T>::value>::type>
  958. void f();
  959. };
  960. )",
  961. Lang_CXX,
  962. functionTemplateDecl(hasName("f")));
  963. EXPECT_FALSE(testStructuralMatch(t));
  964. }
  965. TEST_F(StructuralEquivalenceDependentTemplateArgsTest,
  966. DifferentValueInDependentScopeDeclRefExpr) {
  967. std::string Code =
  968. R"(
  969. template <typename>
  970. struct S1;
  971. template <bool>
  972. struct enable_if;
  973. )";
  974. auto t = makeDecls<FunctionTemplateDecl>(Code + R"(
  975. struct S
  976. {
  977. template <typename T, typename enable_if<S1<T>::value1>::type>
  978. void f(); // DependentScopeDeclRefExpr:^^^^^^^^^^^^
  979. };
  980. )",
  981. Code + R"(
  982. struct S
  983. {
  984. template <typename T, typename enable_if<S1<T>::value2>::type>
  985. void f();
  986. };
  987. )",
  988. Lang_CXX,
  989. functionTemplateDecl(hasName("f")));
  990. EXPECT_FALSE(testStructuralMatch(t));
  991. }
  992. TEST_F(
  993. StructuralEquivalenceTemplateTest,
  994. ClassTemplSpecWithQualifiedAndNonQualifiedTypeArgsShouldBeEqual) {
  995. auto t = makeDecls<ClassTemplateSpecializationDecl>(
  996. R"(
  997. template <class T> struct Primary {};
  998. namespace N {
  999. struct Arg;
  1000. }
  1001. // Explicit instantiation with qualified name.
  1002. template struct Primary<N::Arg>;
  1003. )",
  1004. R"(
  1005. template <class T> struct Primary {};
  1006. namespace N {
  1007. struct Arg;
  1008. }
  1009. using namespace N;
  1010. // Explicit instantiation with UNqualified name.
  1011. template struct Primary<Arg>;
  1012. )",
  1013. Lang_CXX,
  1014. classTemplateSpecializationDecl(hasName("Primary")));
  1015. EXPECT_TRUE(testStructuralMatch(t));
  1016. }
  1017. TEST_F(
  1018. StructuralEquivalenceTemplateTest,
  1019. ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTypeArgs) {
  1020. auto t = makeDecls<ClassTemplateSpecializationDecl>(
  1021. R"(
  1022. template <class T> struct Primary {};
  1023. namespace N {
  1024. struct Arg { int a; };
  1025. }
  1026. // Explicit instantiation with qualified name.
  1027. template struct Primary<N::Arg>;
  1028. )",
  1029. R"(
  1030. template <class T> struct Primary {};
  1031. namespace N {
  1032. // This struct is not equivalent with the other in the prev TU.
  1033. struct Arg { double b; }; // -- Field mismatch.
  1034. }
  1035. using namespace N;
  1036. // Explicit instantiation with UNqualified name.
  1037. template struct Primary<Arg>;
  1038. )",
  1039. Lang_CXX,
  1040. classTemplateSpecializationDecl(hasName("Primary")));
  1041. EXPECT_FALSE(testStructuralMatch(t));
  1042. }
  1043. TEST_F(
  1044. StructuralEquivalenceTemplateTest,
  1045. ClassTemplSpecWithQualifiedAndNonQualifiedTemplArgsShouldBeEqual) {
  1046. auto t = makeDecls<ClassTemplateSpecializationDecl>(
  1047. R"(
  1048. template <template <class> class T> struct Primary {};
  1049. namespace N {
  1050. template <class T> struct Arg;
  1051. }
  1052. // Explicit instantiation with qualified name.
  1053. template struct Primary<N::Arg>;
  1054. )",
  1055. R"(
  1056. template <template <class> class T> struct Primary {};
  1057. namespace N {
  1058. template <class T> struct Arg;
  1059. }
  1060. using namespace N;
  1061. // Explicit instantiation with UNqualified name.
  1062. template struct Primary<Arg>;
  1063. )",
  1064. Lang_CXX,
  1065. classTemplateSpecializationDecl(hasName("Primary")));
  1066. EXPECT_TRUE(testStructuralMatch(t));
  1067. }
  1068. TEST_F(
  1069. StructuralEquivalenceTemplateTest,
  1070. ClassTemplSpecWithInequivalentQualifiedAndNonQualifiedTemplArgs) {
  1071. auto t = makeDecls<ClassTemplateSpecializationDecl>(
  1072. R"(
  1073. template <template <class> class T> struct Primary {};
  1074. namespace N {
  1075. template <class T> struct Arg { int a; };
  1076. }
  1077. // Explicit instantiation with qualified name.
  1078. template struct Primary<N::Arg>;
  1079. )",
  1080. R"(
  1081. template <template <class> class T> struct Primary {};
  1082. namespace N {
  1083. // This template is not equivalent with the other in the prev TU.
  1084. template <class T> struct Arg { double b; }; // -- Field mismatch.
  1085. }
  1086. using namespace N;
  1087. // Explicit instantiation with UNqualified name.
  1088. template struct Primary<Arg>;
  1089. )",
  1090. Lang_CXX,
  1091. classTemplateSpecializationDecl(hasName("Primary")));
  1092. EXPECT_FALSE(testStructuralMatch(t));
  1093. }
  1094. TEST_F(
  1095. StructuralEquivalenceTemplateTest,
  1096. ClassTemplSpecWithInequivalentShadowedTemplArg) {
  1097. auto t = makeDecls<ClassTemplateSpecializationDecl>(
  1098. R"(
  1099. template <template <class> class T> struct Primary {};
  1100. template <class T> struct Arg { int a; };
  1101. // Explicit instantiation with ::Arg
  1102. template struct Primary<Arg>;
  1103. )",
  1104. R"(
  1105. template <template <class> class T> struct Primary {};
  1106. template <class T> struct Arg { int a; };
  1107. namespace N {
  1108. // This template is not equivalent with the other in the global scope.
  1109. template <class T> struct Arg { double b; }; // -- Field mismatch.
  1110. // Explicit instantiation with N::Arg which shadows ::Arg
  1111. template struct Primary<Arg>;
  1112. }
  1113. )",
  1114. Lang_CXX,
  1115. classTemplateSpecializationDecl(hasName("Primary")));
  1116. EXPECT_FALSE(testStructuralMatch(t));
  1117. }
  1118. struct StructuralEquivalenceCacheTest : public StructuralEquivalenceTest {
  1119. llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls;
  1120. template <typename NodeType, typename MatcherType>
  1121. std::pair<NodeType *, NodeType *>
  1122. findDeclPair(std::tuple<TranslationUnitDecl *, TranslationUnitDecl *> TU,
  1123. MatcherType M) {
  1124. NodeType *D0 = FirstDeclMatcher<NodeType>().match(get<0>(TU), M);
  1125. NodeType *D1 = FirstDeclMatcher<NodeType>().match(get<1>(TU), M);
  1126. return {D0, D1};
  1127. }
  1128. template <typename NodeType>
  1129. bool isInNonEqCache(std::pair<NodeType *, NodeType *> D) {
  1130. return NonEquivalentDecls.count(D) > 0;
  1131. }
  1132. };
  1133. TEST_F(StructuralEquivalenceCacheTest, SimpleNonEq) {
  1134. auto TU = makeTuDecls(
  1135. R"(
  1136. class A {};
  1137. class B {};
  1138. void x(A, A);
  1139. )",
  1140. R"(
  1141. class A {};
  1142. class B {};
  1143. void x(A, B);
  1144. )",
  1145. Lang_CXX);
  1146. StructuralEquivalenceContext Ctx(
  1147. get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
  1148. NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
  1149. auto X = findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")));
  1150. EXPECT_FALSE(Ctx.IsEquivalent(X.first, X.second));
  1151. EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
  1152. TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
  1153. EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
  1154. TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
  1155. }
  1156. TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
  1157. auto TU = makeTuDecls(
  1158. R"(
  1159. class A {};
  1160. class B { int i; };
  1161. void x(A *);
  1162. void y(A *);
  1163. class C {
  1164. friend void x(A *);
  1165. friend void y(A *);
  1166. };
  1167. )",
  1168. R"(
  1169. class A {};
  1170. class B { int i; };
  1171. void x(A *);
  1172. void y(B *);
  1173. class C {
  1174. friend void x(A *);
  1175. friend void y(B *);
  1176. };
  1177. )",
  1178. Lang_CXX);
  1179. StructuralEquivalenceContext Ctx(
  1180. get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
  1181. NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
  1182. auto C = findDeclPair<CXXRecordDecl>(
  1183. TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
  1184. EXPECT_FALSE(Ctx.IsEquivalent(C.first, C.second));
  1185. EXPECT_FALSE(isInNonEqCache(C));
  1186. EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
  1187. TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
  1188. EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
  1189. TU, cxxRecordDecl(hasName("B"), unless(isImplicit())))));
  1190. EXPECT_FALSE(isInNonEqCache(
  1191. findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
  1192. EXPECT_FALSE(isInNonEqCache(
  1193. findDeclPair<FunctionDecl>(TU, functionDecl(hasName("y")))));
  1194. }
  1195. TEST_F(StructuralEquivalenceCacheTest, Cycle) {
  1196. auto TU = makeTuDecls(
  1197. R"(
  1198. class C;
  1199. class A { C *c; };
  1200. void x(A *);
  1201. class C {
  1202. friend void x(A *);
  1203. };
  1204. )",
  1205. R"(
  1206. class C;
  1207. class A { C *c; };
  1208. void x(A *);
  1209. class C {
  1210. friend void x(A *);
  1211. };
  1212. )",
  1213. Lang_CXX);
  1214. StructuralEquivalenceContext Ctx(
  1215. get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
  1216. NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
  1217. auto C = findDeclPair<CXXRecordDecl>(
  1218. TU, cxxRecordDecl(hasName("C"), unless(isImplicit())));
  1219. EXPECT_TRUE(Ctx.IsEquivalent(C.first, C.second));
  1220. EXPECT_FALSE(isInNonEqCache(C));
  1221. EXPECT_FALSE(isInNonEqCache(findDeclPair<CXXRecordDecl>(
  1222. TU, cxxRecordDecl(hasName("A"), unless(isImplicit())))));
  1223. EXPECT_FALSE(isInNonEqCache(
  1224. findDeclPair<FunctionDecl>(TU, functionDecl(hasName("x")))));
  1225. }
  1226. } // end namespace ast_matchers
  1227. } // end namespace clang