• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- ASTStructuralEquivalence.cpp ---------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //  This file implement StructuralEquivalenceContext class and helper functions
10 //  for layout matching.
11 //
12 // The structural equivalence check could have been implemented as a parallel
13 // BFS on a pair of graphs.  That must have been the original approach at the
14 // beginning.
15 // Let's consider this simple BFS algorithm from the `s` source:
16 // ```
17 // void bfs(Graph G, int s)
18 // {
19 //   Queue<Integer> queue = new Queue<Integer>();
20 //   marked[s] = true; // Mark the source
21 //   queue.enqueue(s); // and put it on the queue.
22 //   while (!q.isEmpty()) {
23 //     int v = queue.dequeue(); // Remove next vertex from the queue.
24 //     for (int w : G.adj(v))
25 //       if (!marked[w]) // For every unmarked adjacent vertex,
26 //       {
27 //         marked[w] = true;
28 //         queue.enqueue(w);
29 //       }
30 //   }
31 // }
32 // ```
33 // Indeed, it has it's queue, which holds pairs of nodes, one from each graph,
34 // this is the `DeclsToCheck` member. `VisitedDecls` plays the role of the
35 // marking (`marked`) functionality above, we use it to check whether we've
36 // already seen a pair of nodes.
37 //
38 // We put in the elements into the queue only in the toplevel decl check
39 // function:
40 // ```
41 // static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
42 //                                      Decl *D1, Decl *D2);
43 // ```
44 // The `while` loop where we iterate over the children is implemented in
45 // `Finish()`.  And `Finish` is called only from the two **member** functions
46 // which check the equivalency of two Decls or two Types. ASTImporter (and
47 // other clients) call only these functions.
48 //
49 // The `static` implementation functions are called from `Finish`, these push
50 // the children nodes to the queue via `static bool
51 // IsStructurallyEquivalent(StructuralEquivalenceContext &Context, Decl *D1,
52 // Decl *D2)`.  So far so good, this is almost like the BFS.  However, if we
53 // let a static implementation function to call `Finish` via another **member**
54 // function that means we end up with two nested while loops each of them
55 // working on the same queue. This is wrong and nobody can reason about it's
56 // doing. Thus, static implementation functions must not call the **member**
57 // functions.
58 //
59 //===----------------------------------------------------------------------===//
60 
61 #include "clang/AST/ASTStructuralEquivalence.h"
62 #include "clang/AST/ASTContext.h"
63 #include "clang/AST/ASTDiagnostic.h"
64 #include "clang/AST/Decl.h"
65 #include "clang/AST/DeclBase.h"
66 #include "clang/AST/DeclCXX.h"
67 #include "clang/AST/DeclFriend.h"
68 #include "clang/AST/DeclObjC.h"
69 #include "clang/AST/DeclOpenMP.h"
70 #include "clang/AST/DeclTemplate.h"
71 #include "clang/AST/ExprCXX.h"
72 #include "clang/AST/ExprConcepts.h"
73 #include "clang/AST/ExprObjC.h"
74 #include "clang/AST/ExprOpenMP.h"
75 #include "clang/AST/NestedNameSpecifier.h"
76 #include "clang/AST/StmtObjC.h"
77 #include "clang/AST/StmtOpenMP.h"
78 #include "clang/AST/TemplateBase.h"
79 #include "clang/AST/TemplateName.h"
80 #include "clang/AST/Type.h"
81 #include "clang/Basic/ExceptionSpecificationType.h"
82 #include "clang/Basic/IdentifierTable.h"
83 #include "clang/Basic/LLVM.h"
84 #include "clang/Basic/SourceLocation.h"
85 #include "llvm/ADT/APInt.h"
86 #include "llvm/ADT/APSInt.h"
87 #include "llvm/ADT/None.h"
88 #include "llvm/ADT/Optional.h"
89 #include "llvm/Support/Casting.h"
90 #include "llvm/Support/Compiler.h"
91 #include "llvm/Support/ErrorHandling.h"
92 #include <cassert>
93 #include <utility>
94 
95 using namespace clang;
96 
97 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
98                                      QualType T1, QualType T2);
99 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
100                                      Decl *D1, Decl *D2);
101 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
102                                      const TemplateArgument &Arg1,
103                                      const TemplateArgument &Arg2);
104 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
105                                      NestedNameSpecifier *NNS1,
106                                      NestedNameSpecifier *NNS2);
107 static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
108                                      const IdentifierInfo *Name2);
109 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,const DeclarationName Name1,const DeclarationName Name2)110 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
111                                      const DeclarationName Name1,
112                                      const DeclarationName Name2) {
113   if (Name1.getNameKind() != Name2.getNameKind())
114     return false;
115 
116   switch (Name1.getNameKind()) {
117 
118   case DeclarationName::Identifier:
119     return IsStructurallyEquivalent(Name1.getAsIdentifierInfo(),
120                                     Name2.getAsIdentifierInfo());
121 
122   case DeclarationName::CXXConstructorName:
123   case DeclarationName::CXXDestructorName:
124   case DeclarationName::CXXConversionFunctionName:
125     return IsStructurallyEquivalent(Context, Name1.getCXXNameType(),
126                                     Name2.getCXXNameType());
127 
128   case DeclarationName::CXXDeductionGuideName: {
129     if (!IsStructurallyEquivalent(
130             Context, Name1.getCXXDeductionGuideTemplate()->getDeclName(),
131             Name2.getCXXDeductionGuideTemplate()->getDeclName()))
132       return false;
133     return IsStructurallyEquivalent(Context,
134                                     Name1.getCXXDeductionGuideTemplate(),
135                                     Name2.getCXXDeductionGuideTemplate());
136   }
137 
138   case DeclarationName::CXXOperatorName:
139     return Name1.getCXXOverloadedOperator() == Name2.getCXXOverloadedOperator();
140 
141   case DeclarationName::CXXLiteralOperatorName:
142     return IsStructurallyEquivalent(Name1.getCXXLiteralIdentifier(),
143                                     Name2.getCXXLiteralIdentifier());
144 
145   case DeclarationName::CXXUsingDirective:
146     return true; // FIXME When do we consider two using directives equal?
147 
148   case DeclarationName::ObjCZeroArgSelector:
149   case DeclarationName::ObjCOneArgSelector:
150   case DeclarationName::ObjCMultiArgSelector:
151     return true; // FIXME
152   }
153 
154   llvm_unreachable("Unhandled kind of DeclarationName");
155   return true;
156 }
157 
158 namespace {
159 /// Encapsulates Stmt comparison logic.
160 class StmtComparer {
161   StructuralEquivalenceContext &Context;
162 
163   // IsStmtEquivalent overloads. Each overload compares a specific statement
164   // and only has to compare the data that is specific to the specific statement
165   // class. Should only be called from TraverseStmt.
166 
IsStmtEquivalent(const AddrLabelExpr * E1,const AddrLabelExpr * E2)167   bool IsStmtEquivalent(const AddrLabelExpr *E1, const AddrLabelExpr *E2) {
168     return IsStructurallyEquivalent(Context, E1->getLabel(), E2->getLabel());
169   }
170 
IsStmtEquivalent(const AtomicExpr * E1,const AtomicExpr * E2)171   bool IsStmtEquivalent(const AtomicExpr *E1, const AtomicExpr *E2) {
172     return E1->getOp() == E2->getOp();
173   }
174 
IsStmtEquivalent(const BinaryOperator * E1,const BinaryOperator * E2)175   bool IsStmtEquivalent(const BinaryOperator *E1, const BinaryOperator *E2) {
176     return E1->getOpcode() == E2->getOpcode();
177   }
178 
IsStmtEquivalent(const CallExpr * E1,const CallExpr * E2)179   bool IsStmtEquivalent(const CallExpr *E1, const CallExpr *E2) {
180     // FIXME: IsStructurallyEquivalent requires non-const Decls.
181     Decl *Callee1 = const_cast<Decl *>(E1->getCalleeDecl());
182     Decl *Callee2 = const_cast<Decl *>(E2->getCalleeDecl());
183 
184     // Compare whether both calls know their callee.
185     if (static_cast<bool>(Callee1) != static_cast<bool>(Callee2))
186       return false;
187 
188     // Both calls have no callee, so nothing to do.
189     if (!static_cast<bool>(Callee1))
190       return true;
191 
192     assert(Callee2);
193     return IsStructurallyEquivalent(Context, Callee1, Callee2);
194   }
195 
IsStmtEquivalent(const CharacterLiteral * E1,const CharacterLiteral * E2)196   bool IsStmtEquivalent(const CharacterLiteral *E1,
197                         const CharacterLiteral *E2) {
198     return E1->getValue() == E2->getValue() && E1->getKind() == E2->getKind();
199   }
200 
IsStmtEquivalent(const ChooseExpr * E1,const ChooseExpr * E2)201   bool IsStmtEquivalent(const ChooseExpr *E1, const ChooseExpr *E2) {
202     return true; // Semantics only depend on children.
203   }
204 
IsStmtEquivalent(const CompoundStmt * E1,const CompoundStmt * E2)205   bool IsStmtEquivalent(const CompoundStmt *E1, const CompoundStmt *E2) {
206     // Number of children is actually checked by the generic children comparison
207     // code, but a CompoundStmt is one of the few statements where the number of
208     // children frequently differs and the number of statements is also always
209     // precomputed. Directly comparing the number of children here is thus
210     // just an optimization.
211     return E1->size() == E2->size();
212   }
213 
IsStmtEquivalent(const DependentScopeDeclRefExpr * DE1,const DependentScopeDeclRefExpr * DE2)214   bool IsStmtEquivalent(const DependentScopeDeclRefExpr *DE1,
215                         const DependentScopeDeclRefExpr *DE2) {
216     if (!IsStructurallyEquivalent(Context, DE1->getDeclName(),
217                                   DE2->getDeclName()))
218       return false;
219     return IsStructurallyEquivalent(Context, DE1->getQualifier(),
220                                     DE2->getQualifier());
221   }
222 
IsStmtEquivalent(const Expr * E1,const Expr * E2)223   bool IsStmtEquivalent(const Expr *E1, const Expr *E2) {
224     return IsStructurallyEquivalent(Context, E1->getType(), E2->getType());
225   }
226 
IsStmtEquivalent(const ExpressionTraitExpr * E1,const ExpressionTraitExpr * E2)227   bool IsStmtEquivalent(const ExpressionTraitExpr *E1,
228                         const ExpressionTraitExpr *E2) {
229     return E1->getTrait() == E2->getTrait() && E1->getValue() == E2->getValue();
230   }
231 
IsStmtEquivalent(const FloatingLiteral * E1,const FloatingLiteral * E2)232   bool IsStmtEquivalent(const FloatingLiteral *E1, const FloatingLiteral *E2) {
233     return E1->isExact() == E2->isExact() && E1->getValue() == E2->getValue();
234   }
235 
IsStmtEquivalent(const ImplicitCastExpr * CastE1,const ImplicitCastExpr * CastE2)236   bool IsStmtEquivalent(const ImplicitCastExpr *CastE1,
237                         const ImplicitCastExpr *CastE2) {
238     return IsStructurallyEquivalent(Context, CastE1->getType(),
239                                     CastE2->getType());
240   }
241 
IsStmtEquivalent(const IntegerLiteral * E1,const IntegerLiteral * E2)242   bool IsStmtEquivalent(const IntegerLiteral *E1, const IntegerLiteral *E2) {
243     return E1->getValue() == E2->getValue();
244   }
245 
IsStmtEquivalent(const MemberExpr * E1,const MemberExpr * E2)246   bool IsStmtEquivalent(const MemberExpr *E1, const MemberExpr *E2) {
247     return IsStructurallyEquivalent(Context, E1->getFoundDecl(),
248                                     E2->getFoundDecl());
249   }
250 
IsStmtEquivalent(const ObjCStringLiteral * E1,const ObjCStringLiteral * E2)251   bool IsStmtEquivalent(const ObjCStringLiteral *E1,
252                         const ObjCStringLiteral *E2) {
253     // Just wraps a StringLiteral child.
254     return true;
255   }
256 
IsStmtEquivalent(const Stmt * S1,const Stmt * S2)257   bool IsStmtEquivalent(const Stmt *S1, const Stmt *S2) { return true; }
258 
IsStmtEquivalent(const SourceLocExpr * E1,const SourceLocExpr * E2)259   bool IsStmtEquivalent(const SourceLocExpr *E1, const SourceLocExpr *E2) {
260     return E1->getIdentKind() == E2->getIdentKind();
261   }
262 
IsStmtEquivalent(const StmtExpr * E1,const StmtExpr * E2)263   bool IsStmtEquivalent(const StmtExpr *E1, const StmtExpr *E2) {
264     return E1->getTemplateDepth() == E2->getTemplateDepth();
265   }
266 
IsStmtEquivalent(const StringLiteral * E1,const StringLiteral * E2)267   bool IsStmtEquivalent(const StringLiteral *E1, const StringLiteral *E2) {
268     return E1->getBytes() == E2->getBytes();
269   }
270 
IsStmtEquivalent(const SubstNonTypeTemplateParmExpr * E1,const SubstNonTypeTemplateParmExpr * E2)271   bool IsStmtEquivalent(const SubstNonTypeTemplateParmExpr *E1,
272                         const SubstNonTypeTemplateParmExpr *E2) {
273     return IsStructurallyEquivalent(Context, E1->getParameter(),
274                                     E2->getParameter());
275   }
276 
IsStmtEquivalent(const SubstNonTypeTemplateParmPackExpr * E1,const SubstNonTypeTemplateParmPackExpr * E2)277   bool IsStmtEquivalent(const SubstNonTypeTemplateParmPackExpr *E1,
278                         const SubstNonTypeTemplateParmPackExpr *E2) {
279     return IsStructurallyEquivalent(Context, E1->getArgumentPack(),
280                                     E2->getArgumentPack());
281   }
282 
IsStmtEquivalent(const TypeTraitExpr * E1,const TypeTraitExpr * E2)283   bool IsStmtEquivalent(const TypeTraitExpr *E1, const TypeTraitExpr *E2) {
284     if (E1->getTrait() != E2->getTrait())
285       return false;
286 
287     for (auto Pair : zip_longest(E1->getArgs(), E2->getArgs())) {
288       Optional<TypeSourceInfo *> Child1 = std::get<0>(Pair);
289       Optional<TypeSourceInfo *> Child2 = std::get<1>(Pair);
290       // Different number of args.
291       if (!Child1 || !Child2)
292         return false;
293 
294       if (!IsStructurallyEquivalent(Context, (*Child1)->getType(),
295                                     (*Child2)->getType()))
296         return false;
297     }
298     return true;
299   }
300 
IsStmtEquivalent(const UnaryExprOrTypeTraitExpr * E1,const UnaryExprOrTypeTraitExpr * E2)301   bool IsStmtEquivalent(const UnaryExprOrTypeTraitExpr *E1,
302                         const UnaryExprOrTypeTraitExpr *E2) {
303     if (E1->getKind() != E2->getKind())
304       return false;
305     return IsStructurallyEquivalent(Context, E1->getTypeOfArgument(),
306                                     E2->getTypeOfArgument());
307   }
308 
IsStmtEquivalent(const UnaryOperator * E1,const UnaryOperator * E2)309   bool IsStmtEquivalent(const UnaryOperator *E1, const UnaryOperator *E2) {
310     return E1->getOpcode() == E2->getOpcode();
311   }
312 
IsStmtEquivalent(const VAArgExpr * E1,const VAArgExpr * E2)313   bool IsStmtEquivalent(const VAArgExpr *E1, const VAArgExpr *E2) {
314     // Semantics only depend on children.
315     return true;
316   }
317 
318   /// End point of the traversal chain.
TraverseStmt(const Stmt * S1,const Stmt * S2)319   bool TraverseStmt(const Stmt *S1, const Stmt *S2) { return true; }
320 
321   // Create traversal methods that traverse the class hierarchy and return
322   // the accumulated result of the comparison. Each TraverseStmt overload
323   // calls the TraverseStmt overload of the parent class. For example,
324   // the TraverseStmt overload for 'BinaryOperator' calls the TraverseStmt
325   // overload of 'Expr' which then calls the overload for 'Stmt'.
326 #define STMT(CLASS, PARENT)                                                    \
327   bool TraverseStmt(const CLASS *S1, const CLASS *S2) {                        \
328     if (!TraverseStmt(static_cast<const PARENT *>(S1),                         \
329                       static_cast<const PARENT *>(S2)))                        \
330       return false;                                                            \
331     return IsStmtEquivalent(S1, S2);                                           \
332   }
333 #include "clang/AST/StmtNodes.inc"
334 
335 public:
StmtComparer(StructuralEquivalenceContext & C)336   StmtComparer(StructuralEquivalenceContext &C) : Context(C) {}
337 
338   /// Determine whether two statements are equivalent. The statements have to
339   /// be of the same kind. The children of the statements and their properties
340   /// are not compared by this function.
IsEquivalent(const Stmt * S1,const Stmt * S2)341   bool IsEquivalent(const Stmt *S1, const Stmt *S2) {
342     if (S1->getStmtClass() != S2->getStmtClass())
343       return false;
344 
345     // Each TraverseStmt walks the class hierarchy from the leaf class to
346     // the root class 'Stmt' (e.g. 'BinaryOperator' -> 'Expr' -> 'Stmt'). Cast
347     // the Stmt we have here to its specific subclass so that we call the
348     // overload that walks the whole class hierarchy from leaf to root (e.g.,
349     // cast to 'BinaryOperator' so that 'Expr' and 'Stmt' is traversed).
350     switch (S1->getStmtClass()) {
351     case Stmt::NoStmtClass:
352       llvm_unreachable("Can't traverse NoStmtClass");
353 #define STMT(CLASS, PARENT)                                                    \
354   case Stmt::StmtClass::CLASS##Class:                                          \
355     return TraverseStmt(static_cast<const CLASS *>(S1),                        \
356                         static_cast<const CLASS *>(S2));
357 #define ABSTRACT_STMT(S)
358 #include "clang/AST/StmtNodes.inc"
359     }
360     llvm_unreachable("Invalid statement kind");
361   }
362 };
363 } // namespace
364 
365 /// Determine structural equivalence of two statements.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,const Stmt * S1,const Stmt * S2)366 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
367                                      const Stmt *S1, const Stmt *S2) {
368   if (!S1 || !S2)
369     return S1 == S2;
370 
371   // Compare the statements itself.
372   StmtComparer Comparer(Context);
373   if (!Comparer.IsEquivalent(S1, S2))
374     return false;
375 
376   // Iterate over the children of both statements and also compare them.
377   for (auto Pair : zip_longest(S1->children(), S2->children())) {
378     Optional<const Stmt *> Child1 = std::get<0>(Pair);
379     Optional<const Stmt *> Child2 = std::get<1>(Pair);
380     // One of the statements has a different amount of children than the other,
381     // so the statements can't be equivalent.
382     if (!Child1 || !Child2)
383       return false;
384     if (!IsStructurallyEquivalent(Context, *Child1, *Child2))
385       return false;
386   }
387   return true;
388 }
389 
390 /// Determine whether two identifiers are equivalent.
IsStructurallyEquivalent(const IdentifierInfo * Name1,const IdentifierInfo * Name2)391 static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
392                                      const IdentifierInfo *Name2) {
393   if (!Name1 || !Name2)
394     return Name1 == Name2;
395 
396   return Name1->getName() == Name2->getName();
397 }
398 
399 /// Determine whether two nested-name-specifiers are equivalent.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,NestedNameSpecifier * NNS1,NestedNameSpecifier * NNS2)400 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
401                                      NestedNameSpecifier *NNS1,
402                                      NestedNameSpecifier *NNS2) {
403   if (NNS1->getKind() != NNS2->getKind())
404     return false;
405 
406   NestedNameSpecifier *Prefix1 = NNS1->getPrefix(),
407                       *Prefix2 = NNS2->getPrefix();
408   if ((bool)Prefix1 != (bool)Prefix2)
409     return false;
410 
411   if (Prefix1)
412     if (!IsStructurallyEquivalent(Context, Prefix1, Prefix2))
413       return false;
414 
415   switch (NNS1->getKind()) {
416   case NestedNameSpecifier::Identifier:
417     return IsStructurallyEquivalent(NNS1->getAsIdentifier(),
418                                     NNS2->getAsIdentifier());
419   case NestedNameSpecifier::Namespace:
420     return IsStructurallyEquivalent(Context, NNS1->getAsNamespace(),
421                                     NNS2->getAsNamespace());
422   case NestedNameSpecifier::NamespaceAlias:
423     return IsStructurallyEquivalent(Context, NNS1->getAsNamespaceAlias(),
424                                     NNS2->getAsNamespaceAlias());
425   case NestedNameSpecifier::TypeSpec:
426   case NestedNameSpecifier::TypeSpecWithTemplate:
427     return IsStructurallyEquivalent(Context, QualType(NNS1->getAsType(), 0),
428                                     QualType(NNS2->getAsType(), 0));
429   case NestedNameSpecifier::Global:
430     return true;
431   case NestedNameSpecifier::Super:
432     return IsStructurallyEquivalent(Context, NNS1->getAsRecordDecl(),
433                                     NNS2->getAsRecordDecl());
434   }
435   return false;
436 }
437 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,const TemplateName & N1,const TemplateName & N2)438 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
439                                      const TemplateName &N1,
440                                      const TemplateName &N2) {
441   TemplateDecl *TemplateDeclN1 = N1.getAsTemplateDecl();
442   TemplateDecl *TemplateDeclN2 = N2.getAsTemplateDecl();
443   if (TemplateDeclN1 && TemplateDeclN2) {
444     if (!IsStructurallyEquivalent(Context, TemplateDeclN1, TemplateDeclN2))
445       return false;
446     // If the kind is different we compare only the template decl.
447     if (N1.getKind() != N2.getKind())
448       return true;
449   } else if (TemplateDeclN1 || TemplateDeclN2)
450     return false;
451   else if (N1.getKind() != N2.getKind())
452     return false;
453 
454   // Check for special case incompatibilities.
455   switch (N1.getKind()) {
456 
457   case TemplateName::OverloadedTemplate: {
458     OverloadedTemplateStorage *OS1 = N1.getAsOverloadedTemplate(),
459                               *OS2 = N2.getAsOverloadedTemplate();
460     OverloadedTemplateStorage::iterator I1 = OS1->begin(), I2 = OS2->begin(),
461                                         E1 = OS1->end(), E2 = OS2->end();
462     for (; I1 != E1 && I2 != E2; ++I1, ++I2)
463       if (!IsStructurallyEquivalent(Context, *I1, *I2))
464         return false;
465     return I1 == E1 && I2 == E2;
466   }
467 
468   case TemplateName::AssumedTemplate: {
469     AssumedTemplateStorage *TN1 = N1.getAsAssumedTemplateName(),
470                            *TN2 = N1.getAsAssumedTemplateName();
471     return TN1->getDeclName() == TN2->getDeclName();
472   }
473 
474   case TemplateName::DependentTemplate: {
475     DependentTemplateName *DN1 = N1.getAsDependentTemplateName(),
476                           *DN2 = N2.getAsDependentTemplateName();
477     if (!IsStructurallyEquivalent(Context, DN1->getQualifier(),
478                                   DN2->getQualifier()))
479       return false;
480     if (DN1->isIdentifier() && DN2->isIdentifier())
481       return IsStructurallyEquivalent(DN1->getIdentifier(),
482                                       DN2->getIdentifier());
483     else if (DN1->isOverloadedOperator() && DN2->isOverloadedOperator())
484       return DN1->getOperator() == DN2->getOperator();
485     return false;
486   }
487 
488   case TemplateName::SubstTemplateTemplateParmPack: {
489     SubstTemplateTemplateParmPackStorage
490         *P1 = N1.getAsSubstTemplateTemplateParmPack(),
491         *P2 = N2.getAsSubstTemplateTemplateParmPack();
492     return IsStructurallyEquivalent(Context, P1->getArgumentPack(),
493                                     P2->getArgumentPack()) &&
494            IsStructurallyEquivalent(Context, P1->getParameterPack(),
495                                     P2->getParameterPack());
496   }
497 
498    case TemplateName::Template:
499    case TemplateName::QualifiedTemplate:
500    case TemplateName::SubstTemplateTemplateParm:
501      // It is sufficient to check value of getAsTemplateDecl.
502      break;
503 
504   }
505 
506   return true;
507 }
508 
509 /// Determine whether two template arguments are equivalent.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,const TemplateArgument & Arg1,const TemplateArgument & Arg2)510 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
511                                      const TemplateArgument &Arg1,
512                                      const TemplateArgument &Arg2) {
513   if (Arg1.getKind() != Arg2.getKind())
514     return false;
515 
516   switch (Arg1.getKind()) {
517   case TemplateArgument::Null:
518     return true;
519 
520   case TemplateArgument::Type:
521     return IsStructurallyEquivalent(Context, Arg1.getAsType(), Arg2.getAsType());
522 
523   case TemplateArgument::Integral:
524     if (!IsStructurallyEquivalent(Context, Arg1.getIntegralType(),
525                                           Arg2.getIntegralType()))
526       return false;
527 
528     return llvm::APSInt::isSameValue(Arg1.getAsIntegral(),
529                                      Arg2.getAsIntegral());
530 
531   case TemplateArgument::Declaration:
532     return IsStructurallyEquivalent(Context, Arg1.getAsDecl(), Arg2.getAsDecl());
533 
534   case TemplateArgument::NullPtr:
535     return true; // FIXME: Is this correct?
536 
537   case TemplateArgument::Template:
538     return IsStructurallyEquivalent(Context, Arg1.getAsTemplate(),
539                                     Arg2.getAsTemplate());
540 
541   case TemplateArgument::TemplateExpansion:
542     return IsStructurallyEquivalent(Context,
543                                     Arg1.getAsTemplateOrTemplatePattern(),
544                                     Arg2.getAsTemplateOrTemplatePattern());
545 
546   case TemplateArgument::Expression:
547     return IsStructurallyEquivalent(Context, Arg1.getAsExpr(),
548                                     Arg2.getAsExpr());
549 
550   case TemplateArgument::Pack:
551     if (Arg1.pack_size() != Arg2.pack_size())
552       return false;
553 
554     for (unsigned I = 0, N = Arg1.pack_size(); I != N; ++I)
555       if (!IsStructurallyEquivalent(Context, Arg1.pack_begin()[I],
556                                     Arg2.pack_begin()[I]))
557         return false;
558 
559     return true;
560   }
561 
562   llvm_unreachable("Invalid template argument kind");
563 }
564 
565 /// Determine structural equivalence for the common part of array
566 /// types.
IsArrayStructurallyEquivalent(StructuralEquivalenceContext & Context,const ArrayType * Array1,const ArrayType * Array2)567 static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
568                                           const ArrayType *Array1,
569                                           const ArrayType *Array2) {
570   if (!IsStructurallyEquivalent(Context, Array1->getElementType(),
571                                 Array2->getElementType()))
572     return false;
573   if (Array1->getSizeModifier() != Array2->getSizeModifier())
574     return false;
575   if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
576     return false;
577 
578   return true;
579 }
580 
581 /// Determine structural equivalence based on the ExtInfo of functions. This
582 /// is inspired by ASTContext::mergeFunctionTypes(), we compare calling
583 /// conventions bits but must not compare some other bits.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,FunctionType::ExtInfo EI1,FunctionType::ExtInfo EI2)584 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
585                                      FunctionType::ExtInfo EI1,
586                                      FunctionType::ExtInfo EI2) {
587   // Compatible functions must have compatible calling conventions.
588   if (EI1.getCC() != EI2.getCC())
589     return false;
590 
591   // Regparm is part of the calling convention.
592   if (EI1.getHasRegParm() != EI2.getHasRegParm())
593     return false;
594   if (EI1.getRegParm() != EI2.getRegParm())
595     return false;
596 
597   if (EI1.getProducesResult() != EI2.getProducesResult())
598     return false;
599   if (EI1.getNoCallerSavedRegs() != EI2.getNoCallerSavedRegs())
600     return false;
601   if (EI1.getNoCfCheck() != EI2.getNoCfCheck())
602     return false;
603 
604   return true;
605 }
606 
607 /// Check the equivalence of exception specifications.
IsEquivalentExceptionSpec(StructuralEquivalenceContext & Context,const FunctionProtoType * Proto1,const FunctionProtoType * Proto2)608 static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext &Context,
609                                       const FunctionProtoType *Proto1,
610                                       const FunctionProtoType *Proto2) {
611 
612   auto Spec1 = Proto1->getExceptionSpecType();
613   auto Spec2 = Proto2->getExceptionSpecType();
614 
615   if (isUnresolvedExceptionSpec(Spec1) || isUnresolvedExceptionSpec(Spec2))
616     return true;
617 
618   if (Spec1 != Spec2)
619     return false;
620   if (Spec1 == EST_Dynamic) {
621     if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
622       return false;
623     for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
624       if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
625                                     Proto2->getExceptionType(I)))
626         return false;
627     }
628   } else if (isComputedNoexcept(Spec1)) {
629     if (!IsStructurallyEquivalent(Context, Proto1->getNoexceptExpr(),
630                                   Proto2->getNoexceptExpr()))
631       return false;
632   }
633 
634   return true;
635 }
636 
637 /// Determine structural equivalence of two types.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,QualType T1,QualType T2)638 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
639                                      QualType T1, QualType T2) {
640   if (T1.isNull() || T2.isNull())
641     return T1.isNull() && T2.isNull();
642 
643   QualType OrigT1 = T1;
644   QualType OrigT2 = T2;
645 
646   if (!Context.StrictTypeSpelling) {
647     // We aren't being strict about token-to-token equivalence of types,
648     // so map down to the canonical type.
649     T1 = Context.FromCtx.getCanonicalType(T1);
650     T2 = Context.ToCtx.getCanonicalType(T2);
651   }
652 
653   if (T1.getQualifiers() != T2.getQualifiers())
654     return false;
655 
656   Type::TypeClass TC = T1->getTypeClass();
657 
658   if (T1->getTypeClass() != T2->getTypeClass()) {
659     // Compare function types with prototypes vs. without prototypes as if
660     // both did not have prototypes.
661     if (T1->getTypeClass() == Type::FunctionProto &&
662         T2->getTypeClass() == Type::FunctionNoProto)
663       TC = Type::FunctionNoProto;
664     else if (T1->getTypeClass() == Type::FunctionNoProto &&
665              T2->getTypeClass() == Type::FunctionProto)
666       TC = Type::FunctionNoProto;
667     else
668       return false;
669   }
670 
671   switch (TC) {
672   case Type::Builtin:
673     // FIXME: Deal with Char_S/Char_U.
674     if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
675       return false;
676     break;
677 
678   case Type::Complex:
679     if (!IsStructurallyEquivalent(Context,
680                                   cast<ComplexType>(T1)->getElementType(),
681                                   cast<ComplexType>(T2)->getElementType()))
682       return false;
683     break;
684 
685   case Type::Adjusted:
686   case Type::Decayed:
687     if (!IsStructurallyEquivalent(Context,
688                                   cast<AdjustedType>(T1)->getOriginalType(),
689                                   cast<AdjustedType>(T2)->getOriginalType()))
690       return false;
691     break;
692 
693   case Type::Pointer:
694     if (!IsStructurallyEquivalent(Context,
695                                   cast<PointerType>(T1)->getPointeeType(),
696                                   cast<PointerType>(T2)->getPointeeType()))
697       return false;
698     break;
699 
700   case Type::BlockPointer:
701     if (!IsStructurallyEquivalent(Context,
702                                   cast<BlockPointerType>(T1)->getPointeeType(),
703                                   cast<BlockPointerType>(T2)->getPointeeType()))
704       return false;
705     break;
706 
707   case Type::LValueReference:
708   case Type::RValueReference: {
709     const auto *Ref1 = cast<ReferenceType>(T1);
710     const auto *Ref2 = cast<ReferenceType>(T2);
711     if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
712       return false;
713     if (Ref1->isInnerRef() != Ref2->isInnerRef())
714       return false;
715     if (!IsStructurallyEquivalent(Context, Ref1->getPointeeTypeAsWritten(),
716                                   Ref2->getPointeeTypeAsWritten()))
717       return false;
718     break;
719   }
720 
721   case Type::MemberPointer: {
722     const auto *MemPtr1 = cast<MemberPointerType>(T1);
723     const auto *MemPtr2 = cast<MemberPointerType>(T2);
724     if (!IsStructurallyEquivalent(Context, MemPtr1->getPointeeType(),
725                                   MemPtr2->getPointeeType()))
726       return false;
727     if (!IsStructurallyEquivalent(Context, QualType(MemPtr1->getClass(), 0),
728                                   QualType(MemPtr2->getClass(), 0)))
729       return false;
730     break;
731   }
732 
733   case Type::ConstantArray: {
734     const auto *Array1 = cast<ConstantArrayType>(T1);
735     const auto *Array2 = cast<ConstantArrayType>(T2);
736     if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
737       return false;
738 
739     if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
740       return false;
741     break;
742   }
743 
744   case Type::IncompleteArray:
745     if (!IsArrayStructurallyEquivalent(Context, cast<ArrayType>(T1),
746                                        cast<ArrayType>(T2)))
747       return false;
748     break;
749 
750   case Type::VariableArray: {
751     const auto *Array1 = cast<VariableArrayType>(T1);
752     const auto *Array2 = cast<VariableArrayType>(T2);
753     if (!IsStructurallyEquivalent(Context, Array1->getSizeExpr(),
754                                   Array2->getSizeExpr()))
755       return false;
756 
757     if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
758       return false;
759 
760     break;
761   }
762 
763   case Type::DependentSizedArray: {
764     const auto *Array1 = cast<DependentSizedArrayType>(T1);
765     const auto *Array2 = cast<DependentSizedArrayType>(T2);
766     if (!IsStructurallyEquivalent(Context, Array1->getSizeExpr(),
767                                   Array2->getSizeExpr()))
768       return false;
769 
770     if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
771       return false;
772 
773     break;
774   }
775 
776   case Type::DependentAddressSpace: {
777     const auto *DepAddressSpace1 = cast<DependentAddressSpaceType>(T1);
778     const auto *DepAddressSpace2 = cast<DependentAddressSpaceType>(T2);
779     if (!IsStructurallyEquivalent(Context, DepAddressSpace1->getAddrSpaceExpr(),
780                                   DepAddressSpace2->getAddrSpaceExpr()))
781       return false;
782     if (!IsStructurallyEquivalent(Context, DepAddressSpace1->getPointeeType(),
783                                   DepAddressSpace2->getPointeeType()))
784       return false;
785 
786     break;
787   }
788 
789   case Type::DependentSizedExtVector: {
790     const auto *Vec1 = cast<DependentSizedExtVectorType>(T1);
791     const auto *Vec2 = cast<DependentSizedExtVectorType>(T2);
792     if (!IsStructurallyEquivalent(Context, Vec1->getSizeExpr(),
793                                   Vec2->getSizeExpr()))
794       return false;
795     if (!IsStructurallyEquivalent(Context, Vec1->getElementType(),
796                                   Vec2->getElementType()))
797       return false;
798     break;
799   }
800 
801   case Type::DependentVector: {
802     const auto *Vec1 = cast<DependentVectorType>(T1);
803     const auto *Vec2 = cast<DependentVectorType>(T2);
804     if (Vec1->getVectorKind() != Vec2->getVectorKind())
805       return false;
806     if (!IsStructurallyEquivalent(Context, Vec1->getSizeExpr(),
807                                   Vec2->getSizeExpr()))
808       return false;
809     if (!IsStructurallyEquivalent(Context, Vec1->getElementType(),
810                                   Vec2->getElementType()))
811       return false;
812     break;
813   }
814 
815   case Type::Vector:
816   case Type::ExtVector: {
817     const auto *Vec1 = cast<VectorType>(T1);
818     const auto *Vec2 = cast<VectorType>(T2);
819     if (!IsStructurallyEquivalent(Context, Vec1->getElementType(),
820                                   Vec2->getElementType()))
821       return false;
822     if (Vec1->getNumElements() != Vec2->getNumElements())
823       return false;
824     if (Vec1->getVectorKind() != Vec2->getVectorKind())
825       return false;
826     break;
827   }
828 
829   case Type::DependentSizedMatrix: {
830     const DependentSizedMatrixType *Mat1 = cast<DependentSizedMatrixType>(T1);
831     const DependentSizedMatrixType *Mat2 = cast<DependentSizedMatrixType>(T2);
832     // The element types, row and column expressions must be structurally
833     // equivalent.
834     if (!IsStructurallyEquivalent(Context, Mat1->getRowExpr(),
835                                   Mat2->getRowExpr()) ||
836         !IsStructurallyEquivalent(Context, Mat1->getColumnExpr(),
837                                   Mat2->getColumnExpr()) ||
838         !IsStructurallyEquivalent(Context, Mat1->getElementType(),
839                                   Mat2->getElementType()))
840       return false;
841     break;
842   }
843 
844   case Type::ConstantMatrix: {
845     const ConstantMatrixType *Mat1 = cast<ConstantMatrixType>(T1);
846     const ConstantMatrixType *Mat2 = cast<ConstantMatrixType>(T2);
847     // The element types must be structurally equivalent and the number of rows
848     // and columns must match.
849     if (!IsStructurallyEquivalent(Context, Mat1->getElementType(),
850                                   Mat2->getElementType()) ||
851         Mat1->getNumRows() != Mat2->getNumRows() ||
852         Mat1->getNumColumns() != Mat2->getNumColumns())
853       return false;
854     break;
855   }
856 
857   case Type::FunctionProto: {
858     const auto *Proto1 = cast<FunctionProtoType>(T1);
859     const auto *Proto2 = cast<FunctionProtoType>(T2);
860 
861     if (Proto1->getNumParams() != Proto2->getNumParams())
862       return false;
863     for (unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
864       if (!IsStructurallyEquivalent(Context, Proto1->getParamType(I),
865                                     Proto2->getParamType(I)))
866         return false;
867     }
868     if (Proto1->isVariadic() != Proto2->isVariadic())
869       return false;
870 
871     if (Proto1->getMethodQuals() != Proto2->getMethodQuals())
872       return false;
873 
874     // Check exceptions, this information is lost in canonical type.
875     const auto *OrigProto1 =
876         cast<FunctionProtoType>(OrigT1.getDesugaredType(Context.FromCtx));
877     const auto *OrigProto2 =
878         cast<FunctionProtoType>(OrigT2.getDesugaredType(Context.ToCtx));
879     if (!IsEquivalentExceptionSpec(Context, OrigProto1, OrigProto2))
880       return false;
881 
882     // Fall through to check the bits common with FunctionNoProtoType.
883     LLVM_FALLTHROUGH;
884   }
885 
886   case Type::FunctionNoProto: {
887     const auto *Function1 = cast<FunctionType>(T1);
888     const auto *Function2 = cast<FunctionType>(T2);
889     if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
890                                   Function2->getReturnType()))
891       return false;
892     if (!IsStructurallyEquivalent(Context, Function1->getExtInfo(),
893                                   Function2->getExtInfo()))
894       return false;
895     break;
896   }
897 
898   case Type::UnresolvedUsing:
899     if (!IsStructurallyEquivalent(Context,
900                                   cast<UnresolvedUsingType>(T1)->getDecl(),
901                                   cast<UnresolvedUsingType>(T2)->getDecl()))
902       return false;
903     break;
904 
905   case Type::Attributed:
906     if (!IsStructurallyEquivalent(Context,
907                                   cast<AttributedType>(T1)->getModifiedType(),
908                                   cast<AttributedType>(T2)->getModifiedType()))
909       return false;
910     if (!IsStructurallyEquivalent(
911             Context, cast<AttributedType>(T1)->getEquivalentType(),
912             cast<AttributedType>(T2)->getEquivalentType()))
913       return false;
914     break;
915 
916   case Type::Paren:
917     if (!IsStructurallyEquivalent(Context, cast<ParenType>(T1)->getInnerType(),
918                                   cast<ParenType>(T2)->getInnerType()))
919       return false;
920     break;
921 
922   case Type::MacroQualified:
923     if (!IsStructurallyEquivalent(
924             Context, cast<MacroQualifiedType>(T1)->getUnderlyingType(),
925             cast<MacroQualifiedType>(T2)->getUnderlyingType()))
926       return false;
927     break;
928 
929   case Type::Typedef:
930     if (!IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->getDecl(),
931                                   cast<TypedefType>(T2)->getDecl()))
932       return false;
933     break;
934 
935   case Type::TypeOfExpr:
936     if (!IsStructurallyEquivalent(
937             Context, cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
938             cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
939       return false;
940     break;
941 
942   case Type::TypeOf:
943     if (!IsStructurallyEquivalent(Context,
944                                   cast<TypeOfType>(T1)->getUnderlyingType(),
945                                   cast<TypeOfType>(T2)->getUnderlyingType()))
946       return false;
947     break;
948 
949   case Type::UnaryTransform:
950     if (!IsStructurallyEquivalent(
951             Context, cast<UnaryTransformType>(T1)->getUnderlyingType(),
952             cast<UnaryTransformType>(T2)->getUnderlyingType()))
953       return false;
954     break;
955 
956   case Type::Decltype:
957     if (!IsStructurallyEquivalent(Context,
958                                   cast<DecltypeType>(T1)->getUnderlyingExpr(),
959                                   cast<DecltypeType>(T2)->getUnderlyingExpr()))
960       return false;
961     break;
962 
963   case Type::Auto: {
964     auto *Auto1 = cast<AutoType>(T1);
965     auto *Auto2 = cast<AutoType>(T2);
966     if (!IsStructurallyEquivalent(Context, Auto1->getDeducedType(),
967                                   Auto2->getDeducedType()))
968       return false;
969     if (Auto1->isConstrained() != Auto2->isConstrained())
970       return false;
971     if (Auto1->isConstrained()) {
972       if (Auto1->getTypeConstraintConcept() !=
973           Auto2->getTypeConstraintConcept())
974         return false;
975       ArrayRef<TemplateArgument> Auto1Args =
976           Auto1->getTypeConstraintArguments();
977       ArrayRef<TemplateArgument> Auto2Args =
978           Auto2->getTypeConstraintArguments();
979       if (Auto1Args.size() != Auto2Args.size())
980         return false;
981       for (unsigned I = 0, N = Auto1Args.size(); I != N; ++I) {
982         if (!IsStructurallyEquivalent(Context, Auto1Args[I], Auto2Args[I]))
983           return false;
984       }
985     }
986     break;
987   }
988 
989   case Type::DeducedTemplateSpecialization: {
990     const auto *DT1 = cast<DeducedTemplateSpecializationType>(T1);
991     const auto *DT2 = cast<DeducedTemplateSpecializationType>(T2);
992     if (!IsStructurallyEquivalent(Context, DT1->getTemplateName(),
993                                   DT2->getTemplateName()))
994       return false;
995     if (!IsStructurallyEquivalent(Context, DT1->getDeducedType(),
996                                   DT2->getDeducedType()))
997       return false;
998     break;
999   }
1000 
1001   case Type::Record:
1002   case Type::Enum:
1003     if (!IsStructurallyEquivalent(Context, cast<TagType>(T1)->getDecl(),
1004                                   cast<TagType>(T2)->getDecl()))
1005       return false;
1006     break;
1007 
1008   case Type::TemplateTypeParm: {
1009     const auto *Parm1 = cast<TemplateTypeParmType>(T1);
1010     const auto *Parm2 = cast<TemplateTypeParmType>(T2);
1011     if (Parm1->getDepth() != Parm2->getDepth())
1012       return false;
1013     if (Parm1->getIndex() != Parm2->getIndex())
1014       return false;
1015     if (Parm1->isParameterPack() != Parm2->isParameterPack())
1016       return false;
1017 
1018     // Names of template type parameters are never significant.
1019     break;
1020   }
1021 
1022   case Type::SubstTemplateTypeParm: {
1023     const auto *Subst1 = cast<SubstTemplateTypeParmType>(T1);
1024     const auto *Subst2 = cast<SubstTemplateTypeParmType>(T2);
1025     if (!IsStructurallyEquivalent(Context,
1026                                   QualType(Subst1->getReplacedParameter(), 0),
1027                                   QualType(Subst2->getReplacedParameter(), 0)))
1028       return false;
1029     if (!IsStructurallyEquivalent(Context, Subst1->getReplacementType(),
1030                                   Subst2->getReplacementType()))
1031       return false;
1032     break;
1033   }
1034 
1035   case Type::SubstTemplateTypeParmPack: {
1036     const auto *Subst1 = cast<SubstTemplateTypeParmPackType>(T1);
1037     const auto *Subst2 = cast<SubstTemplateTypeParmPackType>(T2);
1038     if (!IsStructurallyEquivalent(Context,
1039                                   QualType(Subst1->getReplacedParameter(), 0),
1040                                   QualType(Subst2->getReplacedParameter(), 0)))
1041       return false;
1042     if (!IsStructurallyEquivalent(Context, Subst1->getArgumentPack(),
1043                                   Subst2->getArgumentPack()))
1044       return false;
1045     break;
1046   }
1047 
1048   case Type::TemplateSpecialization: {
1049     const auto *Spec1 = cast<TemplateSpecializationType>(T1);
1050     const auto *Spec2 = cast<TemplateSpecializationType>(T2);
1051     if (!IsStructurallyEquivalent(Context, Spec1->getTemplateName(),
1052                                   Spec2->getTemplateName()))
1053       return false;
1054     if (Spec1->getNumArgs() != Spec2->getNumArgs())
1055       return false;
1056     for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
1057       if (!IsStructurallyEquivalent(Context, Spec1->getArg(I),
1058                                     Spec2->getArg(I)))
1059         return false;
1060     }
1061     break;
1062   }
1063 
1064   case Type::Elaborated: {
1065     const auto *Elab1 = cast<ElaboratedType>(T1);
1066     const auto *Elab2 = cast<ElaboratedType>(T2);
1067     // CHECKME: what if a keyword is ETK_None or ETK_typename ?
1068     if (Elab1->getKeyword() != Elab2->getKeyword())
1069       return false;
1070     if (!IsStructurallyEquivalent(Context, Elab1->getQualifier(),
1071                                   Elab2->getQualifier()))
1072       return false;
1073     if (!IsStructurallyEquivalent(Context, Elab1->getNamedType(),
1074                                   Elab2->getNamedType()))
1075       return false;
1076     break;
1077   }
1078 
1079   case Type::InjectedClassName: {
1080     const auto *Inj1 = cast<InjectedClassNameType>(T1);
1081     const auto *Inj2 = cast<InjectedClassNameType>(T2);
1082     if (!IsStructurallyEquivalent(Context,
1083                                   Inj1->getInjectedSpecializationType(),
1084                                   Inj2->getInjectedSpecializationType()))
1085       return false;
1086     break;
1087   }
1088 
1089   case Type::DependentName: {
1090     const auto *Typename1 = cast<DependentNameType>(T1);
1091     const auto *Typename2 = cast<DependentNameType>(T2);
1092     if (!IsStructurallyEquivalent(Context, Typename1->getQualifier(),
1093                                   Typename2->getQualifier()))
1094       return false;
1095     if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
1096                                   Typename2->getIdentifier()))
1097       return false;
1098 
1099     break;
1100   }
1101 
1102   case Type::DependentTemplateSpecialization: {
1103     const auto *Spec1 = cast<DependentTemplateSpecializationType>(T1);
1104     const auto *Spec2 = cast<DependentTemplateSpecializationType>(T2);
1105     if (!IsStructurallyEquivalent(Context, Spec1->getQualifier(),
1106                                   Spec2->getQualifier()))
1107       return false;
1108     if (!IsStructurallyEquivalent(Spec1->getIdentifier(),
1109                                   Spec2->getIdentifier()))
1110       return false;
1111     if (Spec1->getNumArgs() != Spec2->getNumArgs())
1112       return false;
1113     for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
1114       if (!IsStructurallyEquivalent(Context, Spec1->getArg(I),
1115                                     Spec2->getArg(I)))
1116         return false;
1117     }
1118     break;
1119   }
1120 
1121   case Type::PackExpansion:
1122     if (!IsStructurallyEquivalent(Context,
1123                                   cast<PackExpansionType>(T1)->getPattern(),
1124                                   cast<PackExpansionType>(T2)->getPattern()))
1125       return false;
1126     break;
1127 
1128   case Type::ObjCInterface: {
1129     const auto *Iface1 = cast<ObjCInterfaceType>(T1);
1130     const auto *Iface2 = cast<ObjCInterfaceType>(T2);
1131     if (!IsStructurallyEquivalent(Context, Iface1->getDecl(),
1132                                   Iface2->getDecl()))
1133       return false;
1134     break;
1135   }
1136 
1137   case Type::ObjCTypeParam: {
1138     const auto *Obj1 = cast<ObjCTypeParamType>(T1);
1139     const auto *Obj2 = cast<ObjCTypeParamType>(T2);
1140     if (!IsStructurallyEquivalent(Context, Obj1->getDecl(), Obj2->getDecl()))
1141       return false;
1142 
1143     if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
1144       return false;
1145     for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
1146       if (!IsStructurallyEquivalent(Context, Obj1->getProtocol(I),
1147                                     Obj2->getProtocol(I)))
1148         return false;
1149     }
1150     break;
1151   }
1152 
1153   case Type::ObjCObject: {
1154     const auto *Obj1 = cast<ObjCObjectType>(T1);
1155     const auto *Obj2 = cast<ObjCObjectType>(T2);
1156     if (!IsStructurallyEquivalent(Context, Obj1->getBaseType(),
1157                                   Obj2->getBaseType()))
1158       return false;
1159     if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
1160       return false;
1161     for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
1162       if (!IsStructurallyEquivalent(Context, Obj1->getProtocol(I),
1163                                     Obj2->getProtocol(I)))
1164         return false;
1165     }
1166     break;
1167   }
1168 
1169   case Type::ObjCObjectPointer: {
1170     const auto *Ptr1 = cast<ObjCObjectPointerType>(T1);
1171     const auto *Ptr2 = cast<ObjCObjectPointerType>(T2);
1172     if (!IsStructurallyEquivalent(Context, Ptr1->getPointeeType(),
1173                                   Ptr2->getPointeeType()))
1174       return false;
1175     break;
1176   }
1177 
1178   case Type::Atomic:
1179     if (!IsStructurallyEquivalent(Context, cast<AtomicType>(T1)->getValueType(),
1180                                   cast<AtomicType>(T2)->getValueType()))
1181       return false;
1182     break;
1183 
1184   case Type::Pipe:
1185     if (!IsStructurallyEquivalent(Context, cast<PipeType>(T1)->getElementType(),
1186                                   cast<PipeType>(T2)->getElementType()))
1187       return false;
1188     break;
1189   case Type::ExtInt: {
1190     const auto *Int1 = cast<ExtIntType>(T1);
1191     const auto *Int2 = cast<ExtIntType>(T2);
1192 
1193     if (Int1->isUnsigned() != Int2->isUnsigned() ||
1194         Int1->getNumBits() != Int2->getNumBits())
1195       return false;
1196     break;
1197   }
1198   case Type::DependentExtInt: {
1199     const auto *Int1 = cast<DependentExtIntType>(T1);
1200     const auto *Int2 = cast<DependentExtIntType>(T2);
1201 
1202     if (Int1->isUnsigned() != Int2->isUnsigned() ||
1203         !IsStructurallyEquivalent(Context, Int1->getNumBitsExpr(),
1204                                   Int2->getNumBitsExpr()))
1205       return false;
1206   }
1207   } // end switch
1208 
1209   return true;
1210 }
1211 
1212 /// Determine structural equivalence of two fields.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,FieldDecl * Field1,FieldDecl * Field2)1213 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1214                                      FieldDecl *Field1, FieldDecl *Field2) {
1215   const auto *Owner2 = cast<RecordDecl>(Field2->getDeclContext());
1216 
1217   // For anonymous structs/unions, match up the anonymous struct/union type
1218   // declarations directly, so that we don't go off searching for anonymous
1219   // types
1220   if (Field1->isAnonymousStructOrUnion() &&
1221       Field2->isAnonymousStructOrUnion()) {
1222     RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getDecl();
1223     RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getDecl();
1224     return IsStructurallyEquivalent(Context, D1, D2);
1225   }
1226 
1227   // Check for equivalent field names.
1228   IdentifierInfo *Name1 = Field1->getIdentifier();
1229   IdentifierInfo *Name2 = Field2->getIdentifier();
1230   if (!::IsStructurallyEquivalent(Name1, Name2)) {
1231     if (Context.Complain) {
1232       Context.Diag2(
1233           Owner2->getLocation(),
1234           Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
1235           << Context.ToCtx.getTypeDeclType(Owner2);
1236       Context.Diag2(Field2->getLocation(), diag::note_odr_field_name)
1237           << Field2->getDeclName();
1238       Context.Diag1(Field1->getLocation(), diag::note_odr_field_name)
1239           << Field1->getDeclName();
1240     }
1241     return false;
1242   }
1243 
1244   if (!IsStructurallyEquivalent(Context, Field1->getType(),
1245                                 Field2->getType())) {
1246     if (Context.Complain) {
1247       Context.Diag2(
1248           Owner2->getLocation(),
1249           Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
1250           << Context.ToCtx.getTypeDeclType(Owner2);
1251       Context.Diag2(Field2->getLocation(), diag::note_odr_field)
1252           << Field2->getDeclName() << Field2->getType();
1253       Context.Diag1(Field1->getLocation(), diag::note_odr_field)
1254           << Field1->getDeclName() << Field1->getType();
1255     }
1256     return false;
1257   }
1258 
1259   if (Field1->isBitField())
1260     return IsStructurallyEquivalent(Context, Field1->getBitWidth(),
1261                                     Field2->getBitWidth());
1262 
1263   return true;
1264 }
1265 
1266 /// Determine structural equivalence of two methods.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,CXXMethodDecl * Method1,CXXMethodDecl * Method2)1267 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1268                                      CXXMethodDecl *Method1,
1269                                      CXXMethodDecl *Method2) {
1270   bool PropertiesEqual =
1271       Method1->getDeclKind() == Method2->getDeclKind() &&
1272       Method1->getRefQualifier() == Method2->getRefQualifier() &&
1273       Method1->getAccess() == Method2->getAccess() &&
1274       Method1->getOverloadedOperator() == Method2->getOverloadedOperator() &&
1275       Method1->isStatic() == Method2->isStatic() &&
1276       Method1->isConst() == Method2->isConst() &&
1277       Method1->isVolatile() == Method2->isVolatile() &&
1278       Method1->isVirtual() == Method2->isVirtual() &&
1279       Method1->isPure() == Method2->isPure() &&
1280       Method1->isDefaulted() == Method2->isDefaulted() &&
1281       Method1->isDeleted() == Method2->isDeleted();
1282   if (!PropertiesEqual)
1283     return false;
1284   // FIXME: Check for 'final'.
1285 
1286   if (auto *Constructor1 = dyn_cast<CXXConstructorDecl>(Method1)) {
1287     auto *Constructor2 = cast<CXXConstructorDecl>(Method2);
1288     if (!Constructor1->getExplicitSpecifier().isEquivalent(
1289             Constructor2->getExplicitSpecifier()))
1290       return false;
1291   }
1292 
1293   if (auto *Conversion1 = dyn_cast<CXXConversionDecl>(Method1)) {
1294     auto *Conversion2 = cast<CXXConversionDecl>(Method2);
1295     if (!Conversion1->getExplicitSpecifier().isEquivalent(
1296             Conversion2->getExplicitSpecifier()))
1297       return false;
1298     if (!IsStructurallyEquivalent(Context, Conversion1->getConversionType(),
1299                                   Conversion2->getConversionType()))
1300       return false;
1301   }
1302 
1303   const IdentifierInfo *Name1 = Method1->getIdentifier();
1304   const IdentifierInfo *Name2 = Method2->getIdentifier();
1305   if (!::IsStructurallyEquivalent(Name1, Name2)) {
1306     return false;
1307     // TODO: Names do not match, add warning like at check for FieldDecl.
1308   }
1309 
1310   // Check the prototypes.
1311   if (!::IsStructurallyEquivalent(Context,
1312                                   Method1->getType(), Method2->getType()))
1313     return false;
1314 
1315   return true;
1316 }
1317 
1318 /// Determine structural equivalence of two lambda classes.
1319 static bool
IsStructurallyEquivalentLambdas(StructuralEquivalenceContext & Context,CXXRecordDecl * D1,CXXRecordDecl * D2)1320 IsStructurallyEquivalentLambdas(StructuralEquivalenceContext &Context,
1321                                 CXXRecordDecl *D1, CXXRecordDecl *D2) {
1322   assert(D1->isLambda() && D2->isLambda() &&
1323          "Must be called on lambda classes");
1324   if (!IsStructurallyEquivalent(Context, D1->getLambdaCallOperator(),
1325                                 D2->getLambdaCallOperator()))
1326     return false;
1327 
1328   return true;
1329 }
1330 
1331 /// Determine structural equivalence of two records.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,RecordDecl * D1,RecordDecl * D2)1332 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1333                                      RecordDecl *D1, RecordDecl *D2) {
1334 
1335   // Check for equivalent structure names.
1336   IdentifierInfo *Name1 = D1->getIdentifier();
1337   if (!Name1 && D1->getTypedefNameForAnonDecl())
1338     Name1 = D1->getTypedefNameForAnonDecl()->getIdentifier();
1339   IdentifierInfo *Name2 = D2->getIdentifier();
1340   if (!Name2 && D2->getTypedefNameForAnonDecl())
1341     Name2 = D2->getTypedefNameForAnonDecl()->getIdentifier();
1342   if (!IsStructurallyEquivalent(Name1, Name2))
1343     return false;
1344 
1345   if (D1->isUnion() != D2->isUnion()) {
1346     if (Context.Complain) {
1347       Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
1348                                            diag::err_odr_tag_type_inconsistent))
1349           << Context.ToCtx.getTypeDeclType(D2);
1350       Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
1351           << D1->getDeclName() << (unsigned)D1->getTagKind();
1352     }
1353     return false;
1354   }
1355 
1356   if (!D1->getDeclName() && !D2->getDeclName()) {
1357     // If both anonymous structs/unions are in a record context, make sure
1358     // they occur in the same location in the context records.
1359     if (Optional<unsigned> Index1 =
1360             StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(D1)) {
1361       if (Optional<unsigned> Index2 =
1362               StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(
1363                   D2)) {
1364         if (*Index1 != *Index2)
1365           return false;
1366       }
1367     }
1368   }
1369 
1370   // If both declarations are class template specializations, we know
1371   // the ODR applies, so check the template and template arguments.
1372   const auto *Spec1 = dyn_cast<ClassTemplateSpecializationDecl>(D1);
1373   const auto *Spec2 = dyn_cast<ClassTemplateSpecializationDecl>(D2);
1374   if (Spec1 && Spec2) {
1375     // Check that the specialized templates are the same.
1376     if (!IsStructurallyEquivalent(Context, Spec1->getSpecializedTemplate(),
1377                                   Spec2->getSpecializedTemplate()))
1378       return false;
1379 
1380     // Check that the template arguments are the same.
1381     if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
1382       return false;
1383 
1384     for (unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
1385       if (!IsStructurallyEquivalent(Context, Spec1->getTemplateArgs().get(I),
1386                                     Spec2->getTemplateArgs().get(I)))
1387         return false;
1388   }
1389   // If one is a class template specialization and the other is not, these
1390   // structures are different.
1391   else if (Spec1 || Spec2)
1392     return false;
1393 
1394   // Compare the definitions of these two records. If either or both are
1395   // incomplete (i.e. it is a forward decl), we assume that they are
1396   // equivalent.
1397   D1 = D1->getDefinition();
1398   D2 = D2->getDefinition();
1399   if (!D1 || !D2)
1400     return true;
1401 
1402   // If any of the records has external storage and we do a minimal check (or
1403   // AST import) we assume they are equivalent. (If we didn't have this
1404   // assumption then `RecordDecl::LoadFieldsFromExternalStorage` could trigger
1405   // another AST import which in turn would call the structural equivalency
1406   // check again and finally we'd have an improper result.)
1407   if (Context.EqKind == StructuralEquivalenceKind::Minimal)
1408     if (D1->hasExternalLexicalStorage() || D2->hasExternalLexicalStorage())
1409       return true;
1410 
1411   // If one definition is currently being defined, we do not compare for
1412   // equality and we assume that the decls are equal.
1413   if (D1->isBeingDefined() || D2->isBeingDefined())
1414     return true;
1415 
1416   if (auto *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
1417     if (auto *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
1418       if (D1CXX->hasExternalLexicalStorage() &&
1419           !D1CXX->isCompleteDefinition()) {
1420         D1CXX->getASTContext().getExternalSource()->CompleteType(D1CXX);
1421       }
1422 
1423       if (D1CXX->isLambda() != D2CXX->isLambda())
1424         return false;
1425       if (D1CXX->isLambda()) {
1426         if (!IsStructurallyEquivalentLambdas(Context, D1CXX, D2CXX))
1427           return false;
1428       }
1429 
1430       if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
1431         if (Context.Complain) {
1432           Context.Diag2(D2->getLocation(),
1433                         Context.getApplicableDiagnostic(
1434                             diag::err_odr_tag_type_inconsistent))
1435               << Context.ToCtx.getTypeDeclType(D2);
1436           Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
1437               << D2CXX->getNumBases();
1438           Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
1439               << D1CXX->getNumBases();
1440         }
1441         return false;
1442       }
1443 
1444       // Check the base classes.
1445       for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(),
1446                                               BaseEnd1 = D1CXX->bases_end(),
1447                                               Base2 = D2CXX->bases_begin();
1448            Base1 != BaseEnd1; ++Base1, ++Base2) {
1449         if (!IsStructurallyEquivalent(Context, Base1->getType(),
1450                                       Base2->getType())) {
1451           if (Context.Complain) {
1452             Context.Diag2(D2->getLocation(),
1453                           Context.getApplicableDiagnostic(
1454                               diag::err_odr_tag_type_inconsistent))
1455                 << Context.ToCtx.getTypeDeclType(D2);
1456             Context.Diag2(Base2->getBeginLoc(), diag::note_odr_base)
1457                 << Base2->getType() << Base2->getSourceRange();
1458             Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1459                 << Base1->getType() << Base1->getSourceRange();
1460           }
1461           return false;
1462         }
1463 
1464         // Check virtual vs. non-virtual inheritance mismatch.
1465         if (Base1->isVirtual() != Base2->isVirtual()) {
1466           if (Context.Complain) {
1467             Context.Diag2(D2->getLocation(),
1468                           Context.getApplicableDiagnostic(
1469                               diag::err_odr_tag_type_inconsistent))
1470                 << Context.ToCtx.getTypeDeclType(D2);
1471             Context.Diag2(Base2->getBeginLoc(), diag::note_odr_virtual_base)
1472                 << Base2->isVirtual() << Base2->getSourceRange();
1473             Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1474                 << Base1->isVirtual() << Base1->getSourceRange();
1475           }
1476           return false;
1477         }
1478       }
1479 
1480       // Check the friends for consistency.
1481       CXXRecordDecl::friend_iterator Friend2 = D2CXX->friend_begin(),
1482                                      Friend2End = D2CXX->friend_end();
1483       for (CXXRecordDecl::friend_iterator Friend1 = D1CXX->friend_begin(),
1484                                           Friend1End = D1CXX->friend_end();
1485            Friend1 != Friend1End; ++Friend1, ++Friend2) {
1486         if (Friend2 == Friend2End) {
1487           if (Context.Complain) {
1488             Context.Diag2(D2->getLocation(),
1489                           Context.getApplicableDiagnostic(
1490                               diag::err_odr_tag_type_inconsistent))
1491                 << Context.ToCtx.getTypeDeclType(D2CXX);
1492             Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1493             Context.Diag2(D2->getLocation(), diag::note_odr_missing_friend);
1494           }
1495           return false;
1496         }
1497 
1498         if (!IsStructurallyEquivalent(Context, *Friend1, *Friend2)) {
1499           if (Context.Complain) {
1500             Context.Diag2(D2->getLocation(),
1501                           Context.getApplicableDiagnostic(
1502                               diag::err_odr_tag_type_inconsistent))
1503                 << Context.ToCtx.getTypeDeclType(D2CXX);
1504             Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1505             Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1506           }
1507           return false;
1508         }
1509       }
1510 
1511       if (Friend2 != Friend2End) {
1512         if (Context.Complain) {
1513           Context.Diag2(D2->getLocation(),
1514                         Context.getApplicableDiagnostic(
1515                             diag::err_odr_tag_type_inconsistent))
1516               << Context.ToCtx.getTypeDeclType(D2);
1517           Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1518           Context.Diag1(D1->getLocation(), diag::note_odr_missing_friend);
1519         }
1520         return false;
1521       }
1522     } else if (D1CXX->getNumBases() > 0) {
1523       if (Context.Complain) {
1524         Context.Diag2(D2->getLocation(),
1525                       Context.getApplicableDiagnostic(
1526                           diag::err_odr_tag_type_inconsistent))
1527             << Context.ToCtx.getTypeDeclType(D2);
1528         const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
1529         Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1530             << Base1->getType() << Base1->getSourceRange();
1531         Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
1532       }
1533       return false;
1534     }
1535   }
1536 
1537   // Check the fields for consistency.
1538   RecordDecl::field_iterator Field2 = D2->field_begin(),
1539                              Field2End = D2->field_end();
1540   for (RecordDecl::field_iterator Field1 = D1->field_begin(),
1541                                   Field1End = D1->field_end();
1542        Field1 != Field1End; ++Field1, ++Field2) {
1543     if (Field2 == Field2End) {
1544       if (Context.Complain) {
1545         Context.Diag2(D2->getLocation(),
1546                       Context.getApplicableDiagnostic(
1547                           diag::err_odr_tag_type_inconsistent))
1548             << Context.ToCtx.getTypeDeclType(D2);
1549         Context.Diag1(Field1->getLocation(), diag::note_odr_field)
1550             << Field1->getDeclName() << Field1->getType();
1551         Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
1552       }
1553       return false;
1554     }
1555 
1556     if (!IsStructurallyEquivalent(Context, *Field1, *Field2))
1557       return false;
1558   }
1559 
1560   if (Field2 != Field2End) {
1561     if (Context.Complain) {
1562       Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
1563                                            diag::err_odr_tag_type_inconsistent))
1564           << Context.ToCtx.getTypeDeclType(D2);
1565       Context.Diag2(Field2->getLocation(), diag::note_odr_field)
1566           << Field2->getDeclName() << Field2->getType();
1567       Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
1568     }
1569     return false;
1570   }
1571 
1572   return true;
1573 }
1574 
1575 /// Determine structural equivalence of two enums.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,EnumDecl * D1,EnumDecl * D2)1576 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1577                                      EnumDecl *D1, EnumDecl *D2) {
1578 
1579   // Check for equivalent enum names.
1580   IdentifierInfo *Name1 = D1->getIdentifier();
1581   if (!Name1 && D1->getTypedefNameForAnonDecl())
1582     Name1 = D1->getTypedefNameForAnonDecl()->getIdentifier();
1583   IdentifierInfo *Name2 = D2->getIdentifier();
1584   if (!Name2 && D2->getTypedefNameForAnonDecl())
1585     Name2 = D2->getTypedefNameForAnonDecl()->getIdentifier();
1586   if (!IsStructurallyEquivalent(Name1, Name2))
1587     return false;
1588 
1589   // Compare the definitions of these two enums. If either or both are
1590   // incomplete (i.e. forward declared), we assume that they are equivalent.
1591   D1 = D1->getDefinition();
1592   D2 = D2->getDefinition();
1593   if (!D1 || !D2)
1594     return true;
1595 
1596   EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
1597                                 EC2End = D2->enumerator_end();
1598   for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
1599                                      EC1End = D1->enumerator_end();
1600        EC1 != EC1End; ++EC1, ++EC2) {
1601     if (EC2 == EC2End) {
1602       if (Context.Complain) {
1603         Context.Diag2(D2->getLocation(),
1604                       Context.getApplicableDiagnostic(
1605                           diag::err_odr_tag_type_inconsistent))
1606             << Context.ToCtx.getTypeDeclType(D2);
1607         Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1608             << EC1->getDeclName() << EC1->getInitVal().toString(10);
1609         Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
1610       }
1611       return false;
1612     }
1613 
1614     llvm::APSInt Val1 = EC1->getInitVal();
1615     llvm::APSInt Val2 = EC2->getInitVal();
1616     if (!llvm::APSInt::isSameValue(Val1, Val2) ||
1617         !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
1618       if (Context.Complain) {
1619         Context.Diag2(D2->getLocation(),
1620                       Context.getApplicableDiagnostic(
1621                           diag::err_odr_tag_type_inconsistent))
1622             << Context.ToCtx.getTypeDeclType(D2);
1623         Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1624             << EC2->getDeclName() << EC2->getInitVal().toString(10);
1625         Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1626             << EC1->getDeclName() << EC1->getInitVal().toString(10);
1627       }
1628       return false;
1629     }
1630   }
1631 
1632   if (EC2 != EC2End) {
1633     if (Context.Complain) {
1634       Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
1635                                            diag::err_odr_tag_type_inconsistent))
1636           << Context.ToCtx.getTypeDeclType(D2);
1637       Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1638           << EC2->getDeclName() << EC2->getInitVal().toString(10);
1639       Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
1640     }
1641     return false;
1642   }
1643 
1644   return true;
1645 }
1646 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,TemplateParameterList * Params1,TemplateParameterList * Params2)1647 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1648                                      TemplateParameterList *Params1,
1649                                      TemplateParameterList *Params2) {
1650   if (Params1->size() != Params2->size()) {
1651     if (Context.Complain) {
1652       Context.Diag2(Params2->getTemplateLoc(),
1653                     Context.getApplicableDiagnostic(
1654                         diag::err_odr_different_num_template_parameters))
1655           << Params1->size() << Params2->size();
1656       Context.Diag1(Params1->getTemplateLoc(),
1657                     diag::note_odr_template_parameter_list);
1658     }
1659     return false;
1660   }
1661 
1662   for (unsigned I = 0, N = Params1->size(); I != N; ++I) {
1663     if (Params1->getParam(I)->getKind() != Params2->getParam(I)->getKind()) {
1664       if (Context.Complain) {
1665         Context.Diag2(Params2->getParam(I)->getLocation(),
1666                       Context.getApplicableDiagnostic(
1667                           diag::err_odr_different_template_parameter_kind));
1668         Context.Diag1(Params1->getParam(I)->getLocation(),
1669                       diag::note_odr_template_parameter_here);
1670       }
1671       return false;
1672     }
1673 
1674     if (!IsStructurallyEquivalent(Context, Params1->getParam(I),
1675                                   Params2->getParam(I)))
1676       return false;
1677   }
1678 
1679   return true;
1680 }
1681 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,TemplateTypeParmDecl * D1,TemplateTypeParmDecl * D2)1682 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1683                                      TemplateTypeParmDecl *D1,
1684                                      TemplateTypeParmDecl *D2) {
1685   if (D1->isParameterPack() != D2->isParameterPack()) {
1686     if (Context.Complain) {
1687       Context.Diag2(D2->getLocation(),
1688                     Context.getApplicableDiagnostic(
1689                         diag::err_odr_parameter_pack_non_pack))
1690           << D2->isParameterPack();
1691       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1692           << D1->isParameterPack();
1693     }
1694     return false;
1695   }
1696 
1697   return true;
1698 }
1699 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,NonTypeTemplateParmDecl * D1,NonTypeTemplateParmDecl * D2)1700 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1701                                      NonTypeTemplateParmDecl *D1,
1702                                      NonTypeTemplateParmDecl *D2) {
1703   if (D1->isParameterPack() != D2->isParameterPack()) {
1704     if (Context.Complain) {
1705       Context.Diag2(D2->getLocation(),
1706                     Context.getApplicableDiagnostic(
1707                         diag::err_odr_parameter_pack_non_pack))
1708           << D2->isParameterPack();
1709       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1710           << D1->isParameterPack();
1711     }
1712     return false;
1713   }
1714 
1715   // Check types.
1716   if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
1717     if (Context.Complain) {
1718       Context.Diag2(D2->getLocation(),
1719                     Context.getApplicableDiagnostic(
1720                         diag::err_odr_non_type_parameter_type_inconsistent))
1721           << D2->getType() << D1->getType();
1722       Context.Diag1(D1->getLocation(), diag::note_odr_value_here)
1723           << D1->getType();
1724     }
1725     return false;
1726   }
1727 
1728   return true;
1729 }
1730 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,TemplateTemplateParmDecl * D1,TemplateTemplateParmDecl * D2)1731 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1732                                      TemplateTemplateParmDecl *D1,
1733                                      TemplateTemplateParmDecl *D2) {
1734   if (D1->isParameterPack() != D2->isParameterPack()) {
1735     if (Context.Complain) {
1736       Context.Diag2(D2->getLocation(),
1737                     Context.getApplicableDiagnostic(
1738                         diag::err_odr_parameter_pack_non_pack))
1739           << D2->isParameterPack();
1740       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1741           << D1->isParameterPack();
1742     }
1743     return false;
1744   }
1745 
1746   // Check template parameter lists.
1747   return IsStructurallyEquivalent(Context, D1->getTemplateParameters(),
1748                                   D2->getTemplateParameters());
1749 }
1750 
IsTemplateDeclCommonStructurallyEquivalent(StructuralEquivalenceContext & Ctx,TemplateDecl * D1,TemplateDecl * D2)1751 static bool IsTemplateDeclCommonStructurallyEquivalent(
1752     StructuralEquivalenceContext &Ctx, TemplateDecl *D1, TemplateDecl *D2) {
1753   if (!IsStructurallyEquivalent(D1->getIdentifier(), D2->getIdentifier()))
1754     return false;
1755   if (!D1->getIdentifier()) // Special name
1756     if (D1->getNameAsString() != D2->getNameAsString())
1757       return false;
1758   return IsStructurallyEquivalent(Ctx, D1->getTemplateParameters(),
1759                                   D2->getTemplateParameters());
1760 }
1761 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,ClassTemplateDecl * D1,ClassTemplateDecl * D2)1762 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1763                                      ClassTemplateDecl *D1,
1764                                      ClassTemplateDecl *D2) {
1765   // Check template parameters.
1766   if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
1767     return false;
1768 
1769   // Check the templated declaration.
1770   return IsStructurallyEquivalent(Context, D1->getTemplatedDecl(),
1771                                   D2->getTemplatedDecl());
1772 }
1773 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,FunctionTemplateDecl * D1,FunctionTemplateDecl * D2)1774 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1775                                      FunctionTemplateDecl *D1,
1776                                      FunctionTemplateDecl *D2) {
1777   // Check template parameters.
1778   if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
1779     return false;
1780 
1781   // Check the templated declaration.
1782   return IsStructurallyEquivalent(Context, D1->getTemplatedDecl()->getType(),
1783                                   D2->getTemplatedDecl()->getType());
1784 }
1785 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,ConceptDecl * D1,ConceptDecl * D2)1786 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1787                                      ConceptDecl *D1,
1788                                      ConceptDecl *D2) {
1789   // Check template parameters.
1790   if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
1791     return false;
1792 
1793   // Check the constraint expression.
1794   return IsStructurallyEquivalent(Context, D1->getConstraintExpr(),
1795                                   D2->getConstraintExpr());
1796 }
1797 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,FriendDecl * D1,FriendDecl * D2)1798 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1799                                      FriendDecl *D1, FriendDecl *D2) {
1800   if ((D1->getFriendType() && D2->getFriendDecl()) ||
1801       (D1->getFriendDecl() && D2->getFriendType())) {
1802       return false;
1803   }
1804   if (D1->getFriendType() && D2->getFriendType())
1805     return IsStructurallyEquivalent(Context,
1806                                     D1->getFriendType()->getType(),
1807                                     D2->getFriendType()->getType());
1808   if (D1->getFriendDecl() && D2->getFriendDecl())
1809     return IsStructurallyEquivalent(Context, D1->getFriendDecl(),
1810                                     D2->getFriendDecl());
1811   return false;
1812 }
1813 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,TypedefNameDecl * D1,TypedefNameDecl * D2)1814 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1815                                      TypedefNameDecl *D1, TypedefNameDecl *D2) {
1816   if (!IsStructurallyEquivalent(D1->getIdentifier(), D2->getIdentifier()))
1817     return false;
1818 
1819   return IsStructurallyEquivalent(Context, D1->getUnderlyingType(),
1820                                   D2->getUnderlyingType());
1821 }
1822 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,FunctionDecl * D1,FunctionDecl * D2)1823 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1824                                      FunctionDecl *D1, FunctionDecl *D2) {
1825   if (!IsStructurallyEquivalent(D1->getIdentifier(), D2->getIdentifier()))
1826     return false;
1827 
1828   if (D1->isOverloadedOperator()) {
1829     if (!D2->isOverloadedOperator())
1830       return false;
1831     if (D1->getOverloadedOperator() != D2->getOverloadedOperator())
1832       return false;
1833   }
1834 
1835   // FIXME: Consider checking for function attributes as well.
1836   if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType()))
1837     return false;
1838 
1839   return true;
1840 }
1841 
1842 /// Determine structural equivalence of two declarations.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,Decl * D1,Decl * D2)1843 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1844                                      Decl *D1, Decl *D2) {
1845   // FIXME: Check for known structural equivalences via a callback of some sort.
1846 
1847   D1 = D1->getCanonicalDecl();
1848   D2 = D2->getCanonicalDecl();
1849   std::pair<Decl *, Decl *> P{D1, D2};
1850 
1851   // Check whether we already know that these two declarations are not
1852   // structurally equivalent.
1853   if (Context.NonEquivalentDecls.count(P))
1854     return false;
1855 
1856   // Check if a check for these declarations is already pending.
1857   // If yes D1 and D2 will be checked later (from DeclsToCheck),
1858   // or these are already checked (and equivalent).
1859   bool Inserted = Context.VisitedDecls.insert(P).second;
1860   if (!Inserted)
1861     return true;
1862 
1863   Context.DeclsToCheck.push(P);
1864 
1865   return true;
1866 }
1867 
Diag1(SourceLocation Loc,unsigned DiagID)1868 DiagnosticBuilder StructuralEquivalenceContext::Diag1(SourceLocation Loc,
1869                                                       unsigned DiagID) {
1870   assert(Complain && "Not allowed to complain");
1871   if (LastDiagFromC2)
1872     FromCtx.getDiagnostics().notePriorDiagnosticFrom(ToCtx.getDiagnostics());
1873   LastDiagFromC2 = false;
1874   return FromCtx.getDiagnostics().Report(Loc, DiagID);
1875 }
1876 
Diag2(SourceLocation Loc,unsigned DiagID)1877 DiagnosticBuilder StructuralEquivalenceContext::Diag2(SourceLocation Loc,
1878                                                       unsigned DiagID) {
1879   assert(Complain && "Not allowed to complain");
1880   if (!LastDiagFromC2)
1881     ToCtx.getDiagnostics().notePriorDiagnosticFrom(FromCtx.getDiagnostics());
1882   LastDiagFromC2 = true;
1883   return ToCtx.getDiagnostics().Report(Loc, DiagID);
1884 }
1885 
1886 Optional<unsigned>
findUntaggedStructOrUnionIndex(RecordDecl * Anon)1887 StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
1888   ASTContext &Context = Anon->getASTContext();
1889   QualType AnonTy = Context.getRecordType(Anon);
1890 
1891   const auto *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext());
1892   if (!Owner)
1893     return None;
1894 
1895   unsigned Index = 0;
1896   for (const auto *D : Owner->noload_decls()) {
1897     const auto *F = dyn_cast<FieldDecl>(D);
1898     if (!F)
1899       continue;
1900 
1901     if (F->isAnonymousStructOrUnion()) {
1902       if (Context.hasSameType(F->getType(), AnonTy))
1903         break;
1904       ++Index;
1905       continue;
1906     }
1907 
1908     // If the field looks like this:
1909     // struct { ... } A;
1910     QualType FieldType = F->getType();
1911     // In case of nested structs.
1912     while (const auto *ElabType = dyn_cast<ElaboratedType>(FieldType))
1913       FieldType = ElabType->getNamedType();
1914 
1915     if (const auto *RecType = dyn_cast<RecordType>(FieldType)) {
1916       const RecordDecl *RecDecl = RecType->getDecl();
1917       if (RecDecl->getDeclContext() == Owner && !RecDecl->getIdentifier()) {
1918         if (Context.hasSameType(FieldType, AnonTy))
1919           break;
1920         ++Index;
1921         continue;
1922       }
1923     }
1924   }
1925 
1926   return Index;
1927 }
1928 
getApplicableDiagnostic(unsigned ErrorDiagnostic)1929 unsigned StructuralEquivalenceContext::getApplicableDiagnostic(
1930     unsigned ErrorDiagnostic) {
1931   if (ErrorOnTagTypeMismatch)
1932     return ErrorDiagnostic;
1933 
1934   switch (ErrorDiagnostic) {
1935   case diag::err_odr_variable_type_inconsistent:
1936     return diag::warn_odr_variable_type_inconsistent;
1937   case diag::err_odr_variable_multiple_def:
1938     return diag::warn_odr_variable_multiple_def;
1939   case diag::err_odr_function_type_inconsistent:
1940     return diag::warn_odr_function_type_inconsistent;
1941   case diag::err_odr_tag_type_inconsistent:
1942     return diag::warn_odr_tag_type_inconsistent;
1943   case diag::err_odr_field_type_inconsistent:
1944     return diag::warn_odr_field_type_inconsistent;
1945   case diag::err_odr_ivar_type_inconsistent:
1946     return diag::warn_odr_ivar_type_inconsistent;
1947   case diag::err_odr_objc_superclass_inconsistent:
1948     return diag::warn_odr_objc_superclass_inconsistent;
1949   case diag::err_odr_objc_method_result_type_inconsistent:
1950     return diag::warn_odr_objc_method_result_type_inconsistent;
1951   case diag::err_odr_objc_method_num_params_inconsistent:
1952     return diag::warn_odr_objc_method_num_params_inconsistent;
1953   case diag::err_odr_objc_method_param_type_inconsistent:
1954     return diag::warn_odr_objc_method_param_type_inconsistent;
1955   case diag::err_odr_objc_method_variadic_inconsistent:
1956     return diag::warn_odr_objc_method_variadic_inconsistent;
1957   case diag::err_odr_objc_property_type_inconsistent:
1958     return diag::warn_odr_objc_property_type_inconsistent;
1959   case diag::err_odr_objc_property_impl_kind_inconsistent:
1960     return diag::warn_odr_objc_property_impl_kind_inconsistent;
1961   case diag::err_odr_objc_synthesize_ivar_inconsistent:
1962     return diag::warn_odr_objc_synthesize_ivar_inconsistent;
1963   case diag::err_odr_different_num_template_parameters:
1964     return diag::warn_odr_different_num_template_parameters;
1965   case diag::err_odr_different_template_parameter_kind:
1966     return diag::warn_odr_different_template_parameter_kind;
1967   case diag::err_odr_parameter_pack_non_pack:
1968     return diag::warn_odr_parameter_pack_non_pack;
1969   case diag::err_odr_non_type_parameter_type_inconsistent:
1970     return diag::warn_odr_non_type_parameter_type_inconsistent;
1971   }
1972   llvm_unreachable("Diagnostic kind not handled in preceding switch");
1973 }
1974 
IsEquivalent(Decl * D1,Decl * D2)1975 bool StructuralEquivalenceContext::IsEquivalent(Decl *D1, Decl *D2) {
1976 
1977   // Ensure that the implementation functions (all static functions in this TU)
1978   // never call the public ASTStructuralEquivalence::IsEquivalent() functions,
1979   // because that will wreak havoc the internal state (DeclsToCheck and
1980   // VisitedDecls members) and can cause faulty behaviour.
1981   // In other words: Do not start a graph search from a new node with the
1982   // internal data of another search in progress.
1983   // FIXME: Better encapsulation and separation of internal and public
1984   // functionality.
1985   assert(DeclsToCheck.empty());
1986   assert(VisitedDecls.empty());
1987 
1988   if (!::IsStructurallyEquivalent(*this, D1, D2))
1989     return false;
1990 
1991   return !Finish();
1992 }
1993 
IsEquivalent(QualType T1,QualType T2)1994 bool StructuralEquivalenceContext::IsEquivalent(QualType T1, QualType T2) {
1995   assert(DeclsToCheck.empty());
1996   assert(VisitedDecls.empty());
1997   if (!::IsStructurallyEquivalent(*this, T1, T2))
1998     return false;
1999 
2000   return !Finish();
2001 }
2002 
IsEquivalent(Stmt * S1,Stmt * S2)2003 bool StructuralEquivalenceContext::IsEquivalent(Stmt *S1, Stmt *S2) {
2004   assert(DeclsToCheck.empty());
2005   assert(VisitedDecls.empty());
2006   if (!::IsStructurallyEquivalent(*this, S1, S2))
2007     return false;
2008 
2009   return !Finish();
2010 }
2011 
CheckCommonEquivalence(Decl * D1,Decl * D2)2012 bool StructuralEquivalenceContext::CheckCommonEquivalence(Decl *D1, Decl *D2) {
2013   // Check for equivalent described template.
2014   TemplateDecl *Template1 = D1->getDescribedTemplate();
2015   TemplateDecl *Template2 = D2->getDescribedTemplate();
2016   if ((Template1 != nullptr) != (Template2 != nullptr))
2017     return false;
2018   if (Template1 && !IsStructurallyEquivalent(*this, Template1, Template2))
2019     return false;
2020 
2021   // FIXME: Move check for identifier names into this function.
2022 
2023   return true;
2024 }
2025 
CheckKindSpecificEquivalence(Decl * D1,Decl * D2)2026 bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
2027     Decl *D1, Decl *D2) {
2028 
2029   // Kind mismatch.
2030   if (D1->getKind() != D2->getKind())
2031     return false;
2032 
2033   // Cast the Decls to their actual subclass so that the right overload of
2034   // IsStructurallyEquivalent is called.
2035   switch (D1->getKind()) {
2036 #define ABSTRACT_DECL(DECL)
2037 #define DECL(DERIVED, BASE)                                                    \
2038   case Decl::Kind::DERIVED:                                                    \
2039     return ::IsStructurallyEquivalent(*this, static_cast<DERIVED##Decl *>(D1), \
2040                                       static_cast<DERIVED##Decl *>(D2));
2041 #include "clang/AST/DeclNodes.inc"
2042   }
2043   return true;
2044 }
2045 
Finish()2046 bool StructuralEquivalenceContext::Finish() {
2047   while (!DeclsToCheck.empty()) {
2048     // Check the next declaration.
2049     std::pair<Decl *, Decl *> P = DeclsToCheck.front();
2050     DeclsToCheck.pop();
2051 
2052     Decl *D1 = P.first;
2053     Decl *D2 = P.second;
2054 
2055     bool Equivalent =
2056         CheckCommonEquivalence(D1, D2) && CheckKindSpecificEquivalence(D1, D2);
2057 
2058     if (!Equivalent) {
2059       // Note that these two declarations are not equivalent (and we already
2060       // know about it).
2061       NonEquivalentDecls.insert(P);
2062 
2063       return true;
2064     }
2065   }
2066 
2067   return false;
2068 }
2069