1 //===- ASTStructuralEquivalence.cpp ---------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implement StructuralEquivalenceContext class and helper functions
10 // for layout matching.
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
15 // Let's consider this simple BFS algorithm from the `s` source:
17 // void bfs(Graph G, int s)
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,
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.
38 // We put in the elements into the queue only in the toplevel decl check
41 // static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
42 // Decl *D1, Decl *D2);
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.
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**
59 //===----------------------------------------------------------------------===//
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/StringExtras.h"
88 #include "llvm/Support/Casting.h"
89 #include "llvm/Support/Compiler.h"
90 #include "llvm/Support/ErrorHandling.h"
95 using namespace clang
;
97 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
98 QualType T1
, QualType T2
);
99 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
101 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
102 const TemplateArgument
&Arg1
,
103 const TemplateArgument
&Arg2
);
104 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
105 const TemplateArgumentLoc
&Arg1
,
106 const TemplateArgumentLoc
&Arg2
);
107 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
108 NestedNameSpecifier
*NNS1
,
109 NestedNameSpecifier
*NNS2
);
110 static bool IsStructurallyEquivalent(const IdentifierInfo
*Name1
,
111 const IdentifierInfo
*Name2
);
113 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
114 const DeclarationName Name1
,
115 const DeclarationName Name2
) {
116 if (Name1
.getNameKind() != Name2
.getNameKind())
119 switch (Name1
.getNameKind()) {
121 case DeclarationName::Identifier
:
122 return IsStructurallyEquivalent(Name1
.getAsIdentifierInfo(),
123 Name2
.getAsIdentifierInfo());
125 case DeclarationName::CXXConstructorName
:
126 case DeclarationName::CXXDestructorName
:
127 case DeclarationName::CXXConversionFunctionName
:
128 return IsStructurallyEquivalent(Context
, Name1
.getCXXNameType(),
129 Name2
.getCXXNameType());
131 case DeclarationName::CXXDeductionGuideName
: {
132 if (!IsStructurallyEquivalent(
133 Context
, Name1
.getCXXDeductionGuideTemplate()->getDeclName(),
134 Name2
.getCXXDeductionGuideTemplate()->getDeclName()))
136 return IsStructurallyEquivalent(Context
,
137 Name1
.getCXXDeductionGuideTemplate(),
138 Name2
.getCXXDeductionGuideTemplate());
141 case DeclarationName::CXXOperatorName
:
142 return Name1
.getCXXOverloadedOperator() == Name2
.getCXXOverloadedOperator();
144 case DeclarationName::CXXLiteralOperatorName
:
145 return IsStructurallyEquivalent(Name1
.getCXXLiteralIdentifier(),
146 Name2
.getCXXLiteralIdentifier());
148 case DeclarationName::CXXUsingDirective
:
149 return true; // FIXME When do we consider two using directives equal?
151 case DeclarationName::ObjCZeroArgSelector
:
152 case DeclarationName::ObjCOneArgSelector
:
153 case DeclarationName::ObjCMultiArgSelector
:
154 return true; // FIXME
157 llvm_unreachable("Unhandled kind of DeclarationName");
162 /// Encapsulates Stmt comparison logic.
164 StructuralEquivalenceContext
&Context
;
166 // IsStmtEquivalent overloads. Each overload compares a specific statement
167 // and only has to compare the data that is specific to the specific statement
168 // class. Should only be called from TraverseStmt.
170 bool IsStmtEquivalent(const AddrLabelExpr
*E1
, const AddrLabelExpr
*E2
) {
171 return IsStructurallyEquivalent(Context
, E1
->getLabel(), E2
->getLabel());
174 bool IsStmtEquivalent(const AtomicExpr
*E1
, const AtomicExpr
*E2
) {
175 return E1
->getOp() == E2
->getOp();
178 bool IsStmtEquivalent(const BinaryOperator
*E1
, const BinaryOperator
*E2
) {
179 return E1
->getOpcode() == E2
->getOpcode();
182 bool IsStmtEquivalent(const CallExpr
*E1
, const CallExpr
*E2
) {
183 // FIXME: IsStructurallyEquivalent requires non-const Decls.
184 Decl
*Callee1
= const_cast<Decl
*>(E1
->getCalleeDecl());
185 Decl
*Callee2
= const_cast<Decl
*>(E2
->getCalleeDecl());
187 // Compare whether both calls know their callee.
188 if (static_cast<bool>(Callee1
) != static_cast<bool>(Callee2
))
191 // Both calls have no callee, so nothing to do.
192 if (!static_cast<bool>(Callee1
))
196 return IsStructurallyEquivalent(Context
, Callee1
, Callee2
);
199 bool IsStmtEquivalent(const CharacterLiteral
*E1
,
200 const CharacterLiteral
*E2
) {
201 return E1
->getValue() == E2
->getValue() && E1
->getKind() == E2
->getKind();
204 bool IsStmtEquivalent(const ChooseExpr
*E1
, const ChooseExpr
*E2
) {
205 return true; // Semantics only depend on children.
208 bool IsStmtEquivalent(const CompoundStmt
*E1
, const CompoundStmt
*E2
) {
209 // Number of children is actually checked by the generic children comparison
210 // code, but a CompoundStmt is one of the few statements where the number of
211 // children frequently differs and the number of statements is also always
212 // precomputed. Directly comparing the number of children here is thus
213 // just an optimization.
214 return E1
->size() == E2
->size();
217 bool IsStmtEquivalent(const DeclRefExpr
*DRE1
, const DeclRefExpr
*DRE2
) {
218 const ValueDecl
*Decl1
= DRE1
->getDecl();
219 const ValueDecl
*Decl2
= DRE2
->getDecl();
220 if (!Decl1
|| !Decl2
)
222 return IsStructurallyEquivalent(Context
, const_cast<ValueDecl
*>(Decl1
),
223 const_cast<ValueDecl
*>(Decl2
));
226 bool IsStmtEquivalent(const DependentScopeDeclRefExpr
*DE1
,
227 const DependentScopeDeclRefExpr
*DE2
) {
228 if (!IsStructurallyEquivalent(Context
, DE1
->getDeclName(),
231 return IsStructurallyEquivalent(Context
, DE1
->getQualifier(),
232 DE2
->getQualifier());
235 bool IsStmtEquivalent(const Expr
*E1
, const Expr
*E2
) {
236 return IsStructurallyEquivalent(Context
, E1
->getType(), E2
->getType());
239 bool IsStmtEquivalent(const ExpressionTraitExpr
*E1
,
240 const ExpressionTraitExpr
*E2
) {
241 return E1
->getTrait() == E2
->getTrait() && E1
->getValue() == E2
->getValue();
244 bool IsStmtEquivalent(const FloatingLiteral
*E1
, const FloatingLiteral
*E2
) {
245 return E1
->isExact() == E2
->isExact() && E1
->getValue() == E2
->getValue();
248 bool IsStmtEquivalent(const GenericSelectionExpr
*E1
,
249 const GenericSelectionExpr
*E2
) {
250 for (auto Pair
: zip_longest(E1
->getAssocTypeSourceInfos(),
251 E2
->getAssocTypeSourceInfos())) {
252 std::optional
<TypeSourceInfo
*> Child1
= std::get
<0>(Pair
);
253 std::optional
<TypeSourceInfo
*> Child2
= std::get
<1>(Pair
);
254 // Skip this case if there are a different number of associated types.
255 if (!Child1
|| !Child2
)
258 if (!IsStructurallyEquivalent(Context
, (*Child1
)->getType(),
259 (*Child2
)->getType()))
266 bool IsStmtEquivalent(const ImplicitCastExpr
*CastE1
,
267 const ImplicitCastExpr
*CastE2
) {
268 return IsStructurallyEquivalent(Context
, CastE1
->getType(),
272 bool IsStmtEquivalent(const IntegerLiteral
*E1
, const IntegerLiteral
*E2
) {
273 return E1
->getValue() == E2
->getValue();
276 bool IsStmtEquivalent(const MemberExpr
*E1
, const MemberExpr
*E2
) {
277 return IsStructurallyEquivalent(Context
, E1
->getFoundDecl(),
281 bool IsStmtEquivalent(const ObjCStringLiteral
*E1
,
282 const ObjCStringLiteral
*E2
) {
283 // Just wraps a StringLiteral child.
287 bool IsStmtEquivalent(const Stmt
*S1
, const Stmt
*S2
) { return true; }
289 bool IsStmtEquivalent(const GotoStmt
*S1
, const GotoStmt
*S2
) {
290 LabelDecl
*L1
= S1
->getLabel();
291 LabelDecl
*L2
= S2
->getLabel();
295 IdentifierInfo
*Name1
= L1
->getIdentifier();
296 IdentifierInfo
*Name2
= L2
->getIdentifier();
297 return ::IsStructurallyEquivalent(Name1
, Name2
);
300 bool IsStmtEquivalent(const SourceLocExpr
*E1
, const SourceLocExpr
*E2
) {
301 return E1
->getIdentKind() == E2
->getIdentKind();
304 bool IsStmtEquivalent(const StmtExpr
*E1
, const StmtExpr
*E2
) {
305 return E1
->getTemplateDepth() == E2
->getTemplateDepth();
308 bool IsStmtEquivalent(const StringLiteral
*E1
, const StringLiteral
*E2
) {
309 return E1
->getBytes() == E2
->getBytes();
312 bool IsStmtEquivalent(const SubstNonTypeTemplateParmExpr
*E1
,
313 const SubstNonTypeTemplateParmExpr
*E2
) {
314 if (!IsStructurallyEquivalent(Context
, E1
->getAssociatedDecl(),
315 E2
->getAssociatedDecl()))
317 if (E1
->getIndex() != E2
->getIndex())
319 if (E1
->getPackIndex() != E2
->getPackIndex())
324 bool IsStmtEquivalent(const SubstNonTypeTemplateParmPackExpr
*E1
,
325 const SubstNonTypeTemplateParmPackExpr
*E2
) {
326 return IsStructurallyEquivalent(Context
, E1
->getArgumentPack(),
327 E2
->getArgumentPack());
330 bool IsStmtEquivalent(const TypeTraitExpr
*E1
, const TypeTraitExpr
*E2
) {
331 if (E1
->getTrait() != E2
->getTrait())
334 for (auto Pair
: zip_longest(E1
->getArgs(), E2
->getArgs())) {
335 std::optional
<TypeSourceInfo
*> Child1
= std::get
<0>(Pair
);
336 std::optional
<TypeSourceInfo
*> Child2
= std::get
<1>(Pair
);
337 // Different number of args.
338 if (!Child1
|| !Child2
)
341 if (!IsStructurallyEquivalent(Context
, (*Child1
)->getType(),
342 (*Child2
)->getType()))
348 bool IsStmtEquivalent(const UnaryExprOrTypeTraitExpr
*E1
,
349 const UnaryExprOrTypeTraitExpr
*E2
) {
350 if (E1
->getKind() != E2
->getKind())
352 return IsStructurallyEquivalent(Context
, E1
->getTypeOfArgument(),
353 E2
->getTypeOfArgument());
356 bool IsStmtEquivalent(const UnaryOperator
*E1
, const UnaryOperator
*E2
) {
357 return E1
->getOpcode() == E2
->getOpcode();
360 bool IsStmtEquivalent(const VAArgExpr
*E1
, const VAArgExpr
*E2
) {
361 // Semantics only depend on children.
365 bool IsStmtEquivalent(const OverloadExpr
*E1
, const OverloadExpr
*E2
) {
366 if (!IsStructurallyEquivalent(Context
, E1
->getName(), E2
->getName()))
369 if (static_cast<bool>(E1
->getQualifier()) !=
370 static_cast<bool>(E2
->getQualifier()))
372 if (E1
->getQualifier() &&
373 !IsStructurallyEquivalent(Context
, E1
->getQualifier(),
377 if (E1
->getNumTemplateArgs() != E2
->getNumTemplateArgs())
379 const TemplateArgumentLoc
*Args1
= E1
->getTemplateArgs();
380 const TemplateArgumentLoc
*Args2
= E2
->getTemplateArgs();
381 for (unsigned int ArgI
= 0, ArgN
= E1
->getNumTemplateArgs(); ArgI
< ArgN
;
383 if (!IsStructurallyEquivalent(Context
, Args1
[ArgI
], Args2
[ArgI
]))
389 bool IsStmtEquivalent(const CXXBoolLiteralExpr
*E1
, const CXXBoolLiteralExpr
*E2
) {
390 return E1
->getValue() == E2
->getValue();
393 /// End point of the traversal chain.
394 bool TraverseStmt(const Stmt
*S1
, const Stmt
*S2
) { return true; }
396 // Create traversal methods that traverse the class hierarchy and return
397 // the accumulated result of the comparison. Each TraverseStmt overload
398 // calls the TraverseStmt overload of the parent class. For example,
399 // the TraverseStmt overload for 'BinaryOperator' calls the TraverseStmt
400 // overload of 'Expr' which then calls the overload for 'Stmt'.
401 #define STMT(CLASS, PARENT) \
402 bool TraverseStmt(const CLASS *S1, const CLASS *S2) { \
403 if (!TraverseStmt(static_cast<const PARENT *>(S1), \
404 static_cast<const PARENT *>(S2))) \
406 return IsStmtEquivalent(S1, S2); \
408 #include "clang/AST/StmtNodes.inc"
411 StmtComparer(StructuralEquivalenceContext
&C
) : Context(C
) {}
413 /// Determine whether two statements are equivalent. The statements have to
414 /// be of the same kind. The children of the statements and their properties
415 /// are not compared by this function.
416 bool IsEquivalent(const Stmt
*S1
, const Stmt
*S2
) {
417 if (S1
->getStmtClass() != S2
->getStmtClass())
420 // Each TraverseStmt walks the class hierarchy from the leaf class to
421 // the root class 'Stmt' (e.g. 'BinaryOperator' -> 'Expr' -> 'Stmt'). Cast
422 // the Stmt we have here to its specific subclass so that we call the
423 // overload that walks the whole class hierarchy from leaf to root (e.g.,
424 // cast to 'BinaryOperator' so that 'Expr' and 'Stmt' is traversed).
425 switch (S1
->getStmtClass()) {
426 case Stmt::NoStmtClass
:
427 llvm_unreachable("Can't traverse NoStmtClass");
428 #define STMT(CLASS, PARENT) \
429 case Stmt::StmtClass::CLASS##Class: \
430 return TraverseStmt(static_cast<const CLASS *>(S1), \
431 static_cast<const CLASS *>(S2));
432 #define ABSTRACT_STMT(S)
433 #include "clang/AST/StmtNodes.inc"
435 llvm_unreachable("Invalid statement kind");
440 /// Determine structural equivalence of two statements.
441 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
442 const Stmt
*S1
, const Stmt
*S2
) {
446 // Compare the statements itself.
447 StmtComparer
Comparer(Context
);
448 if (!Comparer
.IsEquivalent(S1
, S2
))
451 // Iterate over the children of both statements and also compare them.
452 for (auto Pair
: zip_longest(S1
->children(), S2
->children())) {
453 std::optional
<const Stmt
*> Child1
= std::get
<0>(Pair
);
454 std::optional
<const Stmt
*> Child2
= std::get
<1>(Pair
);
455 // One of the statements has a different amount of children than the other,
456 // so the statements can't be equivalent.
457 if (!Child1
|| !Child2
)
459 if (!IsStructurallyEquivalent(Context
, *Child1
, *Child2
))
465 /// Determine whether two identifiers are equivalent.
466 static bool IsStructurallyEquivalent(const IdentifierInfo
*Name1
,
467 const IdentifierInfo
*Name2
) {
468 if (!Name1
|| !Name2
)
469 return Name1
== Name2
;
471 return Name1
->getName() == Name2
->getName();
474 /// Determine whether two nested-name-specifiers are equivalent.
475 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
476 NestedNameSpecifier
*NNS1
,
477 NestedNameSpecifier
*NNS2
) {
478 if (NNS1
->getKind() != NNS2
->getKind())
481 NestedNameSpecifier
*Prefix1
= NNS1
->getPrefix(),
482 *Prefix2
= NNS2
->getPrefix();
483 if ((bool)Prefix1
!= (bool)Prefix2
)
487 if (!IsStructurallyEquivalent(Context
, Prefix1
, Prefix2
))
490 switch (NNS1
->getKind()) {
491 case NestedNameSpecifier::Identifier
:
492 return IsStructurallyEquivalent(NNS1
->getAsIdentifier(),
493 NNS2
->getAsIdentifier());
494 case NestedNameSpecifier::Namespace
:
495 return IsStructurallyEquivalent(Context
, NNS1
->getAsNamespace(),
496 NNS2
->getAsNamespace());
497 case NestedNameSpecifier::NamespaceAlias
:
498 return IsStructurallyEquivalent(Context
, NNS1
->getAsNamespaceAlias(),
499 NNS2
->getAsNamespaceAlias());
500 case NestedNameSpecifier::TypeSpec
:
501 case NestedNameSpecifier::TypeSpecWithTemplate
:
502 return IsStructurallyEquivalent(Context
, QualType(NNS1
->getAsType(), 0),
503 QualType(NNS2
->getAsType(), 0));
504 case NestedNameSpecifier::Global
:
506 case NestedNameSpecifier::Super
:
507 return IsStructurallyEquivalent(Context
, NNS1
->getAsRecordDecl(),
508 NNS2
->getAsRecordDecl());
513 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
514 const TemplateName
&N1
,
515 const TemplateName
&N2
) {
516 TemplateDecl
*TemplateDeclN1
= N1
.getAsTemplateDecl();
517 TemplateDecl
*TemplateDeclN2
= N2
.getAsTemplateDecl();
518 if (TemplateDeclN1
&& TemplateDeclN2
) {
519 if (!IsStructurallyEquivalent(Context
, TemplateDeclN1
, TemplateDeclN2
))
521 // If the kind is different we compare only the template decl.
522 if (N1
.getKind() != N2
.getKind())
524 } else if (TemplateDeclN1
|| TemplateDeclN2
)
526 else if (N1
.getKind() != N2
.getKind())
529 // Check for special case incompatibilities.
530 switch (N1
.getKind()) {
532 case TemplateName::OverloadedTemplate
: {
533 OverloadedTemplateStorage
*OS1
= N1
.getAsOverloadedTemplate(),
534 *OS2
= N2
.getAsOverloadedTemplate();
535 OverloadedTemplateStorage::iterator I1
= OS1
->begin(), I2
= OS2
->begin(),
536 E1
= OS1
->end(), E2
= OS2
->end();
537 for (; I1
!= E1
&& I2
!= E2
; ++I1
, ++I2
)
538 if (!IsStructurallyEquivalent(Context
, *I1
, *I2
))
540 return I1
== E1
&& I2
== E2
;
543 case TemplateName::AssumedTemplate
: {
544 AssumedTemplateStorage
*TN1
= N1
.getAsAssumedTemplateName(),
545 *TN2
= N1
.getAsAssumedTemplateName();
546 return TN1
->getDeclName() == TN2
->getDeclName();
549 case TemplateName::DependentTemplate
: {
550 DependentTemplateName
*DN1
= N1
.getAsDependentTemplateName(),
551 *DN2
= N2
.getAsDependentTemplateName();
552 if (!IsStructurallyEquivalent(Context
, DN1
->getQualifier(),
553 DN2
->getQualifier()))
555 if (DN1
->isIdentifier() && DN2
->isIdentifier())
556 return IsStructurallyEquivalent(DN1
->getIdentifier(),
557 DN2
->getIdentifier());
558 else if (DN1
->isOverloadedOperator() && DN2
->isOverloadedOperator())
559 return DN1
->getOperator() == DN2
->getOperator();
563 case TemplateName::SubstTemplateTemplateParmPack
: {
564 SubstTemplateTemplateParmPackStorage
565 *P1
= N1
.getAsSubstTemplateTemplateParmPack(),
566 *P2
= N2
.getAsSubstTemplateTemplateParmPack();
567 return IsStructurallyEquivalent(Context
, P1
->getArgumentPack(),
568 P2
->getArgumentPack()) &&
569 IsStructurallyEquivalent(Context
, P1
->getAssociatedDecl(),
570 P2
->getAssociatedDecl()) &&
571 P1
->getIndex() == P2
->getIndex();
574 case TemplateName::Template
:
575 case TemplateName::QualifiedTemplate
:
576 case TemplateName::SubstTemplateTemplateParm
:
577 case TemplateName::UsingTemplate
:
578 // It is sufficient to check value of getAsTemplateDecl.
586 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
587 ArrayRef
<TemplateArgument
> Args1
,
588 ArrayRef
<TemplateArgument
> Args2
);
590 /// Determine whether two template arguments are equivalent.
591 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
592 const TemplateArgument
&Arg1
,
593 const TemplateArgument
&Arg2
) {
594 if (Arg1
.getKind() != Arg2
.getKind())
597 switch (Arg1
.getKind()) {
598 case TemplateArgument::Null
:
601 case TemplateArgument::Type
:
602 return IsStructurallyEquivalent(Context
, Arg1
.getAsType(), Arg2
.getAsType());
604 case TemplateArgument::Integral
:
605 if (!IsStructurallyEquivalent(Context
, Arg1
.getIntegralType(),
606 Arg2
.getIntegralType()))
609 return llvm::APSInt::isSameValue(Arg1
.getAsIntegral(),
610 Arg2
.getAsIntegral());
612 case TemplateArgument::Declaration
:
613 return IsStructurallyEquivalent(Context
, Arg1
.getAsDecl(), Arg2
.getAsDecl());
615 case TemplateArgument::NullPtr
:
616 return true; // FIXME: Is this correct?
618 case TemplateArgument::Template
:
619 return IsStructurallyEquivalent(Context
, Arg1
.getAsTemplate(),
620 Arg2
.getAsTemplate());
622 case TemplateArgument::TemplateExpansion
:
623 return IsStructurallyEquivalent(Context
,
624 Arg1
.getAsTemplateOrTemplatePattern(),
625 Arg2
.getAsTemplateOrTemplatePattern());
627 case TemplateArgument::Expression
:
628 return IsStructurallyEquivalent(Context
, Arg1
.getAsExpr(),
631 case TemplateArgument::Pack
:
632 return IsStructurallyEquivalent(Context
, Arg1
.pack_elements(),
633 Arg2
.pack_elements());
636 llvm_unreachable("Invalid template argument kind");
639 /// Determine structural equivalence of two template argument lists.
640 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
641 ArrayRef
<TemplateArgument
> Args1
,
642 ArrayRef
<TemplateArgument
> Args2
) {
643 if (Args1
.size() != Args2
.size())
645 for (unsigned I
= 0, N
= Args1
.size(); I
!= N
; ++I
) {
646 if (!IsStructurallyEquivalent(Context
, Args1
[I
], Args2
[I
]))
652 /// Determine whether two template argument locations are equivalent.
653 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
654 const TemplateArgumentLoc
&Arg1
,
655 const TemplateArgumentLoc
&Arg2
) {
656 return IsStructurallyEquivalent(Context
, Arg1
.getArgument(),
660 /// Determine structural equivalence for the common part of array
662 static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
663 const ArrayType
*Array1
,
664 const ArrayType
*Array2
) {
665 if (!IsStructurallyEquivalent(Context
, Array1
->getElementType(),
666 Array2
->getElementType()))
668 if (Array1
->getSizeModifier() != Array2
->getSizeModifier())
670 if (Array1
->getIndexTypeQualifiers() != Array2
->getIndexTypeQualifiers())
676 /// Determine structural equivalence based on the ExtInfo of functions. This
677 /// is inspired by ASTContext::mergeFunctionTypes(), we compare calling
678 /// conventions bits but must not compare some other bits.
679 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
680 FunctionType::ExtInfo EI1
,
681 FunctionType::ExtInfo EI2
) {
682 // Compatible functions must have compatible calling conventions.
683 if (EI1
.getCC() != EI2
.getCC())
686 // Regparm is part of the calling convention.
687 if (EI1
.getHasRegParm() != EI2
.getHasRegParm())
689 if (EI1
.getRegParm() != EI2
.getRegParm())
692 if (EI1
.getProducesResult() != EI2
.getProducesResult())
694 if (EI1
.getNoCallerSavedRegs() != EI2
.getNoCallerSavedRegs())
696 if (EI1
.getNoCfCheck() != EI2
.getNoCfCheck())
702 /// Check the equivalence of exception specifications.
703 static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext
&Context
,
704 const FunctionProtoType
*Proto1
,
705 const FunctionProtoType
*Proto2
) {
707 auto Spec1
= Proto1
->getExceptionSpecType();
708 auto Spec2
= Proto2
->getExceptionSpecType();
710 if (isUnresolvedExceptionSpec(Spec1
) || isUnresolvedExceptionSpec(Spec2
))
715 if (Spec1
== EST_Dynamic
) {
716 if (Proto1
->getNumExceptions() != Proto2
->getNumExceptions())
718 for (unsigned I
= 0, N
= Proto1
->getNumExceptions(); I
!= N
; ++I
) {
719 if (!IsStructurallyEquivalent(Context
, Proto1
->getExceptionType(I
),
720 Proto2
->getExceptionType(I
)))
723 } else if (isComputedNoexcept(Spec1
)) {
724 if (!IsStructurallyEquivalent(Context
, Proto1
->getNoexceptExpr(),
725 Proto2
->getNoexceptExpr()))
732 /// Determine structural equivalence of two types.
733 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
734 QualType T1
, QualType T2
) {
735 if (T1
.isNull() || T2
.isNull())
736 return T1
.isNull() && T2
.isNull();
738 QualType OrigT1
= T1
;
739 QualType OrigT2
= T2
;
741 if (!Context
.StrictTypeSpelling
) {
742 // We aren't being strict about token-to-token equivalence of types,
743 // so map down to the canonical type.
744 T1
= Context
.FromCtx
.getCanonicalType(T1
);
745 T2
= Context
.ToCtx
.getCanonicalType(T2
);
748 if (T1
.getQualifiers() != T2
.getQualifiers())
751 Type::TypeClass TC
= T1
->getTypeClass();
753 if (T1
->getTypeClass() != T2
->getTypeClass()) {
754 // Compare function types with prototypes vs. without prototypes as if
755 // both did not have prototypes.
756 if (T1
->getTypeClass() == Type::FunctionProto
&&
757 T2
->getTypeClass() == Type::FunctionNoProto
)
758 TC
= Type::FunctionNoProto
;
759 else if (T1
->getTypeClass() == Type::FunctionNoProto
&&
760 T2
->getTypeClass() == Type::FunctionProto
)
761 TC
= Type::FunctionNoProto
;
768 // FIXME: Deal with Char_S/Char_U.
769 if (cast
<BuiltinType
>(T1
)->getKind() != cast
<BuiltinType
>(T2
)->getKind())
774 if (!IsStructurallyEquivalent(Context
,
775 cast
<ComplexType
>(T1
)->getElementType(),
776 cast
<ComplexType
>(T2
)->getElementType()))
782 if (!IsStructurallyEquivalent(Context
,
783 cast
<AdjustedType
>(T1
)->getOriginalType(),
784 cast
<AdjustedType
>(T2
)->getOriginalType()))
789 if (!IsStructurallyEquivalent(Context
,
790 cast
<PointerType
>(T1
)->getPointeeType(),
791 cast
<PointerType
>(T2
)->getPointeeType()))
795 case Type::BlockPointer
:
796 if (!IsStructurallyEquivalent(Context
,
797 cast
<BlockPointerType
>(T1
)->getPointeeType(),
798 cast
<BlockPointerType
>(T2
)->getPointeeType()))
802 case Type::LValueReference
:
803 case Type::RValueReference
: {
804 const auto *Ref1
= cast
<ReferenceType
>(T1
);
805 const auto *Ref2
= cast
<ReferenceType
>(T2
);
806 if (Ref1
->isSpelledAsLValue() != Ref2
->isSpelledAsLValue())
808 if (Ref1
->isInnerRef() != Ref2
->isInnerRef())
810 if (!IsStructurallyEquivalent(Context
, Ref1
->getPointeeTypeAsWritten(),
811 Ref2
->getPointeeTypeAsWritten()))
816 case Type::MemberPointer
: {
817 const auto *MemPtr1
= cast
<MemberPointerType
>(T1
);
818 const auto *MemPtr2
= cast
<MemberPointerType
>(T2
);
819 if (!IsStructurallyEquivalent(Context
, MemPtr1
->getPointeeType(),
820 MemPtr2
->getPointeeType()))
822 if (!IsStructurallyEquivalent(Context
, QualType(MemPtr1
->getClass(), 0),
823 QualType(MemPtr2
->getClass(), 0)))
828 case Type::ConstantArray
: {
829 const auto *Array1
= cast
<ConstantArrayType
>(T1
);
830 const auto *Array2
= cast
<ConstantArrayType
>(T2
);
831 if (!llvm::APInt::isSameValue(Array1
->getSize(), Array2
->getSize()))
834 if (!IsArrayStructurallyEquivalent(Context
, Array1
, Array2
))
839 case Type::IncompleteArray
:
840 if (!IsArrayStructurallyEquivalent(Context
, cast
<ArrayType
>(T1
),
841 cast
<ArrayType
>(T2
)))
845 case Type::VariableArray
: {
846 const auto *Array1
= cast
<VariableArrayType
>(T1
);
847 const auto *Array2
= cast
<VariableArrayType
>(T2
);
848 if (!IsStructurallyEquivalent(Context
, Array1
->getSizeExpr(),
849 Array2
->getSizeExpr()))
852 if (!IsArrayStructurallyEquivalent(Context
, Array1
, Array2
))
858 case Type::DependentSizedArray
: {
859 const auto *Array1
= cast
<DependentSizedArrayType
>(T1
);
860 const auto *Array2
= cast
<DependentSizedArrayType
>(T2
);
861 if (!IsStructurallyEquivalent(Context
, Array1
->getSizeExpr(),
862 Array2
->getSizeExpr()))
865 if (!IsArrayStructurallyEquivalent(Context
, Array1
, Array2
))
871 case Type::DependentAddressSpace
: {
872 const auto *DepAddressSpace1
= cast
<DependentAddressSpaceType
>(T1
);
873 const auto *DepAddressSpace2
= cast
<DependentAddressSpaceType
>(T2
);
874 if (!IsStructurallyEquivalent(Context
, DepAddressSpace1
->getAddrSpaceExpr(),
875 DepAddressSpace2
->getAddrSpaceExpr()))
877 if (!IsStructurallyEquivalent(Context
, DepAddressSpace1
->getPointeeType(),
878 DepAddressSpace2
->getPointeeType()))
884 case Type::DependentSizedExtVector
: {
885 const auto *Vec1
= cast
<DependentSizedExtVectorType
>(T1
);
886 const auto *Vec2
= cast
<DependentSizedExtVectorType
>(T2
);
887 if (!IsStructurallyEquivalent(Context
, Vec1
->getSizeExpr(),
888 Vec2
->getSizeExpr()))
890 if (!IsStructurallyEquivalent(Context
, Vec1
->getElementType(),
891 Vec2
->getElementType()))
896 case Type::DependentVector
: {
897 const auto *Vec1
= cast
<DependentVectorType
>(T1
);
898 const auto *Vec2
= cast
<DependentVectorType
>(T2
);
899 if (Vec1
->getVectorKind() != Vec2
->getVectorKind())
901 if (!IsStructurallyEquivalent(Context
, Vec1
->getSizeExpr(),
902 Vec2
->getSizeExpr()))
904 if (!IsStructurallyEquivalent(Context
, Vec1
->getElementType(),
905 Vec2
->getElementType()))
911 case Type::ExtVector
: {
912 const auto *Vec1
= cast
<VectorType
>(T1
);
913 const auto *Vec2
= cast
<VectorType
>(T2
);
914 if (!IsStructurallyEquivalent(Context
, Vec1
->getElementType(),
915 Vec2
->getElementType()))
917 if (Vec1
->getNumElements() != Vec2
->getNumElements())
919 if (Vec1
->getVectorKind() != Vec2
->getVectorKind())
924 case Type::DependentSizedMatrix
: {
925 const DependentSizedMatrixType
*Mat1
= cast
<DependentSizedMatrixType
>(T1
);
926 const DependentSizedMatrixType
*Mat2
= cast
<DependentSizedMatrixType
>(T2
);
927 // The element types, row and column expressions must be structurally
929 if (!IsStructurallyEquivalent(Context
, Mat1
->getRowExpr(),
930 Mat2
->getRowExpr()) ||
931 !IsStructurallyEquivalent(Context
, Mat1
->getColumnExpr(),
932 Mat2
->getColumnExpr()) ||
933 !IsStructurallyEquivalent(Context
, Mat1
->getElementType(),
934 Mat2
->getElementType()))
939 case Type::ConstantMatrix
: {
940 const ConstantMatrixType
*Mat1
= cast
<ConstantMatrixType
>(T1
);
941 const ConstantMatrixType
*Mat2
= cast
<ConstantMatrixType
>(T2
);
942 // The element types must be structurally equivalent and the number of rows
943 // and columns must match.
944 if (!IsStructurallyEquivalent(Context
, Mat1
->getElementType(),
945 Mat2
->getElementType()) ||
946 Mat1
->getNumRows() != Mat2
->getNumRows() ||
947 Mat1
->getNumColumns() != Mat2
->getNumColumns())
952 case Type::FunctionProto
: {
953 const auto *Proto1
= cast
<FunctionProtoType
>(T1
);
954 const auto *Proto2
= cast
<FunctionProtoType
>(T2
);
956 if (Proto1
->getNumParams() != Proto2
->getNumParams())
958 for (unsigned I
= 0, N
= Proto1
->getNumParams(); I
!= N
; ++I
) {
959 if (!IsStructurallyEquivalent(Context
, Proto1
->getParamType(I
),
960 Proto2
->getParamType(I
)))
963 if (Proto1
->isVariadic() != Proto2
->isVariadic())
966 if (Proto1
->getMethodQuals() != Proto2
->getMethodQuals())
969 // Check exceptions, this information is lost in canonical type.
970 const auto *OrigProto1
=
971 cast
<FunctionProtoType
>(OrigT1
.getDesugaredType(Context
.FromCtx
));
972 const auto *OrigProto2
=
973 cast
<FunctionProtoType
>(OrigT2
.getDesugaredType(Context
.ToCtx
));
974 if (!IsEquivalentExceptionSpec(Context
, OrigProto1
, OrigProto2
))
977 // Fall through to check the bits common with FunctionNoProtoType.
981 case Type::FunctionNoProto
: {
982 const auto *Function1
= cast
<FunctionType
>(T1
);
983 const auto *Function2
= cast
<FunctionType
>(T2
);
984 if (!IsStructurallyEquivalent(Context
, Function1
->getReturnType(),
985 Function2
->getReturnType()))
987 if (!IsStructurallyEquivalent(Context
, Function1
->getExtInfo(),
988 Function2
->getExtInfo()))
993 case Type::UnresolvedUsing
:
994 if (!IsStructurallyEquivalent(Context
,
995 cast
<UnresolvedUsingType
>(T1
)->getDecl(),
996 cast
<UnresolvedUsingType
>(T2
)->getDecl()))
1000 case Type::Attributed
:
1001 if (!IsStructurallyEquivalent(Context
,
1002 cast
<AttributedType
>(T1
)->getModifiedType(),
1003 cast
<AttributedType
>(T2
)->getModifiedType()))
1005 if (!IsStructurallyEquivalent(
1006 Context
, cast
<AttributedType
>(T1
)->getEquivalentType(),
1007 cast
<AttributedType
>(T2
)->getEquivalentType()))
1011 case Type::BTFTagAttributed
:
1012 if (!IsStructurallyEquivalent(
1013 Context
, cast
<BTFTagAttributedType
>(T1
)->getWrappedType(),
1014 cast
<BTFTagAttributedType
>(T2
)->getWrappedType()))
1019 if (!IsStructurallyEquivalent(Context
, cast
<ParenType
>(T1
)->getInnerType(),
1020 cast
<ParenType
>(T2
)->getInnerType()))
1024 case Type::MacroQualified
:
1025 if (!IsStructurallyEquivalent(
1026 Context
, cast
<MacroQualifiedType
>(T1
)->getUnderlyingType(),
1027 cast
<MacroQualifiedType
>(T2
)->getUnderlyingType()))
1032 if (!IsStructurallyEquivalent(Context
, cast
<UsingType
>(T1
)->getFoundDecl(),
1033 cast
<UsingType
>(T2
)->getFoundDecl()))
1035 if (!IsStructurallyEquivalent(Context
,
1036 cast
<UsingType
>(T1
)->getUnderlyingType(),
1037 cast
<UsingType
>(T2
)->getUnderlyingType()))
1042 if (!IsStructurallyEquivalent(Context
, cast
<TypedefType
>(T1
)->getDecl(),
1043 cast
<TypedefType
>(T2
)->getDecl()) ||
1044 !IsStructurallyEquivalent(Context
, cast
<TypedefType
>(T1
)->desugar(),
1045 cast
<TypedefType
>(T2
)->desugar()))
1049 case Type::TypeOfExpr
:
1050 if (!IsStructurallyEquivalent(
1051 Context
, cast
<TypeOfExprType
>(T1
)->getUnderlyingExpr(),
1052 cast
<TypeOfExprType
>(T2
)->getUnderlyingExpr()))
1057 if (!IsStructurallyEquivalent(Context
,
1058 cast
<TypeOfType
>(T1
)->getUnmodifiedType(),
1059 cast
<TypeOfType
>(T2
)->getUnmodifiedType()))
1063 case Type::UnaryTransform
:
1064 if (!IsStructurallyEquivalent(
1065 Context
, cast
<UnaryTransformType
>(T1
)->getUnderlyingType(),
1066 cast
<UnaryTransformType
>(T2
)->getUnderlyingType()))
1070 case Type::Decltype
:
1071 if (!IsStructurallyEquivalent(Context
,
1072 cast
<DecltypeType
>(T1
)->getUnderlyingExpr(),
1073 cast
<DecltypeType
>(T2
)->getUnderlyingExpr()))
1078 auto *Auto1
= cast
<AutoType
>(T1
);
1079 auto *Auto2
= cast
<AutoType
>(T2
);
1080 if (!IsStructurallyEquivalent(Context
, Auto1
->getDeducedType(),
1081 Auto2
->getDeducedType()))
1083 if (Auto1
->isConstrained() != Auto2
->isConstrained())
1085 if (Auto1
->isConstrained()) {
1086 if (Auto1
->getTypeConstraintConcept() !=
1087 Auto2
->getTypeConstraintConcept())
1089 if (!IsStructurallyEquivalent(Context
,
1090 Auto1
->getTypeConstraintArguments(),
1091 Auto2
->getTypeConstraintArguments()))
1097 case Type::DeducedTemplateSpecialization
: {
1098 const auto *DT1
= cast
<DeducedTemplateSpecializationType
>(T1
);
1099 const auto *DT2
= cast
<DeducedTemplateSpecializationType
>(T2
);
1100 if (!IsStructurallyEquivalent(Context
, DT1
->getTemplateName(),
1101 DT2
->getTemplateName()))
1103 if (!IsStructurallyEquivalent(Context
, DT1
->getDeducedType(),
1104 DT2
->getDeducedType()))
1111 if (!IsStructurallyEquivalent(Context
, cast
<TagType
>(T1
)->getDecl(),
1112 cast
<TagType
>(T2
)->getDecl()))
1116 case Type::TemplateTypeParm
: {
1117 const auto *Parm1
= cast
<TemplateTypeParmType
>(T1
);
1118 const auto *Parm2
= cast
<TemplateTypeParmType
>(T2
);
1119 if (!Context
.IgnoreTemplateParmDepth
&&
1120 Parm1
->getDepth() != Parm2
->getDepth())
1122 if (Parm1
->getIndex() != Parm2
->getIndex())
1124 if (Parm1
->isParameterPack() != Parm2
->isParameterPack())
1127 // Names of template type parameters are never significant.
1131 case Type::SubstTemplateTypeParm
: {
1132 const auto *Subst1
= cast
<SubstTemplateTypeParmType
>(T1
);
1133 const auto *Subst2
= cast
<SubstTemplateTypeParmType
>(T2
);
1134 if (!IsStructurallyEquivalent(Context
, Subst1
->getReplacementType(),
1135 Subst2
->getReplacementType()))
1137 if (!IsStructurallyEquivalent(Context
, Subst1
->getAssociatedDecl(),
1138 Subst2
->getAssociatedDecl()))
1140 if (Subst1
->getIndex() != Subst2
->getIndex())
1142 if (Subst1
->getPackIndex() != Subst2
->getPackIndex())
1147 case Type::SubstTemplateTypeParmPack
: {
1148 const auto *Subst1
= cast
<SubstTemplateTypeParmPackType
>(T1
);
1149 const auto *Subst2
= cast
<SubstTemplateTypeParmPackType
>(T2
);
1150 if (!IsStructurallyEquivalent(Context
, Subst1
->getAssociatedDecl(),
1151 Subst2
->getAssociatedDecl()))
1153 if (Subst1
->getIndex() != Subst2
->getIndex())
1155 if (!IsStructurallyEquivalent(Context
, Subst1
->getArgumentPack(),
1156 Subst2
->getArgumentPack()))
1161 case Type::TemplateSpecialization
: {
1162 const auto *Spec1
= cast
<TemplateSpecializationType
>(T1
);
1163 const auto *Spec2
= cast
<TemplateSpecializationType
>(T2
);
1164 if (!IsStructurallyEquivalent(Context
, Spec1
->getTemplateName(),
1165 Spec2
->getTemplateName()))
1167 if (!IsStructurallyEquivalent(Context
, Spec1
->template_arguments(),
1168 Spec2
->template_arguments()))
1173 case Type::Elaborated
: {
1174 const auto *Elab1
= cast
<ElaboratedType
>(T1
);
1175 const auto *Elab2
= cast
<ElaboratedType
>(T2
);
1176 // CHECKME: what if a keyword is ElaboratedTypeKeyword::None or
1177 // ElaboratedTypeKeyword::Typename
1179 if (Elab1
->getKeyword() != Elab2
->getKeyword())
1181 if (!IsStructurallyEquivalent(Context
, Elab1
->getQualifier(),
1182 Elab2
->getQualifier()))
1184 if (!IsStructurallyEquivalent(Context
, Elab1
->getNamedType(),
1185 Elab2
->getNamedType()))
1190 case Type::InjectedClassName
: {
1191 const auto *Inj1
= cast
<InjectedClassNameType
>(T1
);
1192 const auto *Inj2
= cast
<InjectedClassNameType
>(T2
);
1193 if (!IsStructurallyEquivalent(Context
,
1194 Inj1
->getInjectedSpecializationType(),
1195 Inj2
->getInjectedSpecializationType()))
1200 case Type::DependentName
: {
1201 const auto *Typename1
= cast
<DependentNameType
>(T1
);
1202 const auto *Typename2
= cast
<DependentNameType
>(T2
);
1203 if (!IsStructurallyEquivalent(Context
, Typename1
->getQualifier(),
1204 Typename2
->getQualifier()))
1206 if (!IsStructurallyEquivalent(Typename1
->getIdentifier(),
1207 Typename2
->getIdentifier()))
1213 case Type::DependentTemplateSpecialization
: {
1214 const auto *Spec1
= cast
<DependentTemplateSpecializationType
>(T1
);
1215 const auto *Spec2
= cast
<DependentTemplateSpecializationType
>(T2
);
1216 if (!IsStructurallyEquivalent(Context
, Spec1
->getQualifier(),
1217 Spec2
->getQualifier()))
1219 if (!IsStructurallyEquivalent(Spec1
->getIdentifier(),
1220 Spec2
->getIdentifier()))
1222 if (!IsStructurallyEquivalent(Context
, Spec1
->template_arguments(),
1223 Spec2
->template_arguments()))
1228 case Type::PackExpansion
:
1229 if (!IsStructurallyEquivalent(Context
,
1230 cast
<PackExpansionType
>(T1
)->getPattern(),
1231 cast
<PackExpansionType
>(T2
)->getPattern()))
1235 case Type::ObjCInterface
: {
1236 const auto *Iface1
= cast
<ObjCInterfaceType
>(T1
);
1237 const auto *Iface2
= cast
<ObjCInterfaceType
>(T2
);
1238 if (!IsStructurallyEquivalent(Context
, Iface1
->getDecl(),
1244 case Type::ObjCTypeParam
: {
1245 const auto *Obj1
= cast
<ObjCTypeParamType
>(T1
);
1246 const auto *Obj2
= cast
<ObjCTypeParamType
>(T2
);
1247 if (!IsStructurallyEquivalent(Context
, Obj1
->getDecl(), Obj2
->getDecl()))
1250 if (Obj1
->getNumProtocols() != Obj2
->getNumProtocols())
1252 for (unsigned I
= 0, N
= Obj1
->getNumProtocols(); I
!= N
; ++I
) {
1253 if (!IsStructurallyEquivalent(Context
, Obj1
->getProtocol(I
),
1254 Obj2
->getProtocol(I
)))
1260 case Type::ObjCObject
: {
1261 const auto *Obj1
= cast
<ObjCObjectType
>(T1
);
1262 const auto *Obj2
= cast
<ObjCObjectType
>(T2
);
1263 if (!IsStructurallyEquivalent(Context
, Obj1
->getBaseType(),
1264 Obj2
->getBaseType()))
1266 if (Obj1
->getNumProtocols() != Obj2
->getNumProtocols())
1268 for (unsigned I
= 0, N
= Obj1
->getNumProtocols(); I
!= N
; ++I
) {
1269 if (!IsStructurallyEquivalent(Context
, Obj1
->getProtocol(I
),
1270 Obj2
->getProtocol(I
)))
1276 case Type::ObjCObjectPointer
: {
1277 const auto *Ptr1
= cast
<ObjCObjectPointerType
>(T1
);
1278 const auto *Ptr2
= cast
<ObjCObjectPointerType
>(T2
);
1279 if (!IsStructurallyEquivalent(Context
, Ptr1
->getPointeeType(),
1280 Ptr2
->getPointeeType()))
1286 if (!IsStructurallyEquivalent(Context
, cast
<AtomicType
>(T1
)->getValueType(),
1287 cast
<AtomicType
>(T2
)->getValueType()))
1292 if (!IsStructurallyEquivalent(Context
, cast
<PipeType
>(T1
)->getElementType(),
1293 cast
<PipeType
>(T2
)->getElementType()))
1296 case Type::BitInt
: {
1297 const auto *Int1
= cast
<BitIntType
>(T1
);
1298 const auto *Int2
= cast
<BitIntType
>(T2
);
1300 if (Int1
->isUnsigned() != Int2
->isUnsigned() ||
1301 Int1
->getNumBits() != Int2
->getNumBits())
1305 case Type::DependentBitInt
: {
1306 const auto *Int1
= cast
<DependentBitIntType
>(T1
);
1307 const auto *Int2
= cast
<DependentBitIntType
>(T2
);
1309 if (Int1
->isUnsigned() != Int2
->isUnsigned() ||
1310 !IsStructurallyEquivalent(Context
, Int1
->getNumBitsExpr(),
1311 Int2
->getNumBitsExpr()))
1320 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1321 VarDecl
*D1
, VarDecl
*D2
) {
1322 if (D1
->getStorageClass() != D2
->getStorageClass())
1325 IdentifierInfo
*Name1
= D1
->getIdentifier();
1326 IdentifierInfo
*Name2
= D2
->getIdentifier();
1327 if (!::IsStructurallyEquivalent(Name1
, Name2
))
1330 if (!IsStructurallyEquivalent(Context
, D1
->getType(), D2
->getType()))
1333 return IsStructurallyEquivalent(Context
, D1
->getInit(), D2
->getInit());
1336 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1337 FieldDecl
*Field1
, FieldDecl
*Field2
,
1338 QualType Owner2Type
) {
1339 const auto *Owner2
= cast
<Decl
>(Field2
->getDeclContext());
1341 // For anonymous structs/unions, match up the anonymous struct/union type
1342 // declarations directly, so that we don't go off searching for anonymous
1344 if (Field1
->isAnonymousStructOrUnion() &&
1345 Field2
->isAnonymousStructOrUnion()) {
1346 RecordDecl
*D1
= Field1
->getType()->castAs
<RecordType
>()->getDecl();
1347 RecordDecl
*D2
= Field2
->getType()->castAs
<RecordType
>()->getDecl();
1348 return IsStructurallyEquivalent(Context
, D1
, D2
);
1351 // Check for equivalent field names.
1352 IdentifierInfo
*Name1
= Field1
->getIdentifier();
1353 IdentifierInfo
*Name2
= Field2
->getIdentifier();
1354 if (!::IsStructurallyEquivalent(Name1
, Name2
)) {
1355 if (Context
.Complain
) {
1357 Owner2
->getLocation(),
1358 Context
.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent
))
1360 Context
.Diag2(Field2
->getLocation(), diag::note_odr_field_name
)
1361 << Field2
->getDeclName();
1362 Context
.Diag1(Field1
->getLocation(), diag::note_odr_field_name
)
1363 << Field1
->getDeclName();
1368 if (!IsStructurallyEquivalent(Context
, Field1
->getType(),
1369 Field2
->getType())) {
1370 if (Context
.Complain
) {
1372 Owner2
->getLocation(),
1373 Context
.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent
))
1375 Context
.Diag2(Field2
->getLocation(), diag::note_odr_field
)
1376 << Field2
->getDeclName() << Field2
->getType();
1377 Context
.Diag1(Field1
->getLocation(), diag::note_odr_field
)
1378 << Field1
->getDeclName() << Field1
->getType();
1383 if (Field1
->isBitField())
1384 return IsStructurallyEquivalent(Context
, Field1
->getBitWidth(),
1385 Field2
->getBitWidth());
1390 /// Determine structural equivalence of two fields.
1391 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1392 FieldDecl
*Field1
, FieldDecl
*Field2
) {
1393 const auto *Owner2
= cast
<RecordDecl
>(Field2
->getDeclContext());
1394 return IsStructurallyEquivalent(Context
, Field1
, Field2
,
1395 Context
.ToCtx
.getTypeDeclType(Owner2
));
1398 /// Determine structural equivalence of two methods.
1399 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1400 CXXMethodDecl
*Method1
,
1401 CXXMethodDecl
*Method2
) {
1402 bool PropertiesEqual
=
1403 Method1
->getDeclKind() == Method2
->getDeclKind() &&
1404 Method1
->getRefQualifier() == Method2
->getRefQualifier() &&
1405 Method1
->getAccess() == Method2
->getAccess() &&
1406 Method1
->getOverloadedOperator() == Method2
->getOverloadedOperator() &&
1407 Method1
->isStatic() == Method2
->isStatic() &&
1408 Method1
->isImplicitObjectMemberFunction() ==
1409 Method2
->isImplicitObjectMemberFunction() &&
1410 Method1
->isConst() == Method2
->isConst() &&
1411 Method1
->isVolatile() == Method2
->isVolatile() &&
1412 Method1
->isVirtual() == Method2
->isVirtual() &&
1413 Method1
->isPure() == Method2
->isPure() &&
1414 Method1
->isDefaulted() == Method2
->isDefaulted() &&
1415 Method1
->isDeleted() == Method2
->isDeleted();
1416 if (!PropertiesEqual
)
1418 // FIXME: Check for 'final'.
1420 if (auto *Constructor1
= dyn_cast
<CXXConstructorDecl
>(Method1
)) {
1421 auto *Constructor2
= cast
<CXXConstructorDecl
>(Method2
);
1422 if (!Constructor1
->getExplicitSpecifier().isEquivalent(
1423 Constructor2
->getExplicitSpecifier()))
1427 if (auto *Conversion1
= dyn_cast
<CXXConversionDecl
>(Method1
)) {
1428 auto *Conversion2
= cast
<CXXConversionDecl
>(Method2
);
1429 if (!Conversion1
->getExplicitSpecifier().isEquivalent(
1430 Conversion2
->getExplicitSpecifier()))
1432 if (!IsStructurallyEquivalent(Context
, Conversion1
->getConversionType(),
1433 Conversion2
->getConversionType()))
1437 const IdentifierInfo
*Name1
= Method1
->getIdentifier();
1438 const IdentifierInfo
*Name2
= Method2
->getIdentifier();
1439 if (!::IsStructurallyEquivalent(Name1
, Name2
)) {
1441 // TODO: Names do not match, add warning like at check for FieldDecl.
1444 // Check the prototypes.
1445 if (!::IsStructurallyEquivalent(Context
,
1446 Method1
->getType(), Method2
->getType()))
1452 /// Determine structural equivalence of two lambda classes.
1454 IsStructurallyEquivalentLambdas(StructuralEquivalenceContext
&Context
,
1455 CXXRecordDecl
*D1
, CXXRecordDecl
*D2
) {
1456 assert(D1
->isLambda() && D2
->isLambda() &&
1457 "Must be called on lambda classes");
1458 if (!IsStructurallyEquivalent(Context
, D1
->getLambdaCallOperator(),
1459 D2
->getLambdaCallOperator()))
1465 /// Determine if context of a class is equivalent.
1466 static bool IsRecordContextStructurallyEquivalent(RecordDecl
*D1
,
1468 // The context should be completely equal, including anonymous and inline
1470 // We compare objects as part of full translation units, not subtrees of
1471 // translation units.
1472 DeclContext
*DC1
= D1
->getDeclContext()->getNonTransparentContext();
1473 DeclContext
*DC2
= D2
->getDeclContext()->getNonTransparentContext();
1475 // Special case: We allow a struct defined in a function to be equivalent
1476 // with a similar struct defined outside of a function.
1477 if ((DC1
->isFunctionOrMethod() && DC2
->isTranslationUnit()) ||
1478 (DC2
->isFunctionOrMethod() && DC1
->isTranslationUnit()))
1481 if (DC1
->getDeclKind() != DC2
->getDeclKind())
1483 if (DC1
->isTranslationUnit())
1485 if (DC1
->isInlineNamespace() != DC2
->isInlineNamespace())
1487 if (const auto *ND1
= dyn_cast
<NamedDecl
>(DC1
)) {
1488 const auto *ND2
= cast
<NamedDecl
>(DC2
);
1489 if (!DC1
->isInlineNamespace() &&
1490 !IsStructurallyEquivalent(ND1
->getIdentifier(), ND2
->getIdentifier()))
1494 DC1
= DC1
->getParent()->getNonTransparentContext();
1495 DC2
= DC2
->getParent()->getNonTransparentContext();
1501 static bool NameIsStructurallyEquivalent(const TagDecl
&D1
, const TagDecl
&D2
) {
1502 auto GetName
= [](const TagDecl
&D
) -> const IdentifierInfo
* {
1503 if (const IdentifierInfo
*Name
= D
.getIdentifier())
1505 if (const TypedefNameDecl
*TypedefName
= D
.getTypedefNameForAnonDecl())
1506 return TypedefName
->getIdentifier();
1509 return IsStructurallyEquivalent(GetName(D1
), GetName(D2
));
1512 /// Determine structural equivalence of two records.
1513 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1514 RecordDecl
*D1
, RecordDecl
*D2
) {
1515 if (!NameIsStructurallyEquivalent(*D1
, *D2
)) {
1519 if (D1
->isUnion() != D2
->isUnion()) {
1520 if (Context
.Complain
) {
1521 Context
.Diag2(D2
->getLocation(), Context
.getApplicableDiagnostic(
1522 diag::err_odr_tag_type_inconsistent
))
1523 << Context
.ToCtx
.getTypeDeclType(D2
);
1524 Context
.Diag1(D1
->getLocation(), diag::note_odr_tag_kind_here
)
1525 << D1
->getDeclName() << (unsigned)D1
->getTagKind();
1530 if (!D1
->getDeclName() && !D2
->getDeclName()) {
1531 // If both anonymous structs/unions are in a record context, make sure
1532 // they occur in the same location in the context records.
1533 if (std::optional
<unsigned> Index1
=
1534 StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(D1
)) {
1535 if (std::optional
<unsigned> Index2
=
1536 StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(
1538 if (*Index1
!= *Index2
)
1544 // If the records occur in different context (namespace), these should be
1545 // different. This is specially important if the definition of one or both
1546 // records is missing.
1547 if (!IsRecordContextStructurallyEquivalent(D1
, D2
))
1550 // If both declarations are class template specializations, we know
1551 // the ODR applies, so check the template and template arguments.
1552 const auto *Spec1
= dyn_cast
<ClassTemplateSpecializationDecl
>(D1
);
1553 const auto *Spec2
= dyn_cast
<ClassTemplateSpecializationDecl
>(D2
);
1554 if (Spec1
&& Spec2
) {
1555 // Check that the specialized templates are the same.
1556 if (!IsStructurallyEquivalent(Context
, Spec1
->getSpecializedTemplate(),
1557 Spec2
->getSpecializedTemplate()))
1560 // Check that the template arguments are the same.
1561 if (Spec1
->getTemplateArgs().size() != Spec2
->getTemplateArgs().size())
1564 for (unsigned I
= 0, N
= Spec1
->getTemplateArgs().size(); I
!= N
; ++I
)
1565 if (!IsStructurallyEquivalent(Context
, Spec1
->getTemplateArgs().get(I
),
1566 Spec2
->getTemplateArgs().get(I
)))
1569 // If one is a class template specialization and the other is not, these
1570 // structures are different.
1571 else if (Spec1
|| Spec2
)
1574 // Compare the definitions of these two records. If either or both are
1575 // incomplete (i.e. it is a forward decl), we assume that they are
1577 D1
= D1
->getDefinition();
1578 D2
= D2
->getDefinition();
1582 // If any of the records has external storage and we do a minimal check (or
1583 // AST import) we assume they are equivalent. (If we didn't have this
1584 // assumption then `RecordDecl::LoadFieldsFromExternalStorage` could trigger
1585 // another AST import which in turn would call the structural equivalency
1586 // check again and finally we'd have an improper result.)
1587 if (Context
.EqKind
== StructuralEquivalenceKind::Minimal
)
1588 if (D1
->hasExternalLexicalStorage() || D2
->hasExternalLexicalStorage())
1591 // If one definition is currently being defined, we do not compare for
1592 // equality and we assume that the decls are equal.
1593 if (D1
->isBeingDefined() || D2
->isBeingDefined())
1596 if (auto *D1CXX
= dyn_cast
<CXXRecordDecl
>(D1
)) {
1597 if (auto *D2CXX
= dyn_cast
<CXXRecordDecl
>(D2
)) {
1598 if (D1CXX
->hasExternalLexicalStorage() &&
1599 !D1CXX
->isCompleteDefinition()) {
1600 D1CXX
->getASTContext().getExternalSource()->CompleteType(D1CXX
);
1603 if (D1CXX
->isLambda() != D2CXX
->isLambda())
1605 if (D1CXX
->isLambda()) {
1606 if (!IsStructurallyEquivalentLambdas(Context
, D1CXX
, D2CXX
))
1610 if (D1CXX
->getNumBases() != D2CXX
->getNumBases()) {
1611 if (Context
.Complain
) {
1612 Context
.Diag2(D2
->getLocation(),
1613 Context
.getApplicableDiagnostic(
1614 diag::err_odr_tag_type_inconsistent
))
1615 << Context
.ToCtx
.getTypeDeclType(D2
);
1616 Context
.Diag2(D2
->getLocation(), diag::note_odr_number_of_bases
)
1617 << D2CXX
->getNumBases();
1618 Context
.Diag1(D1
->getLocation(), diag::note_odr_number_of_bases
)
1619 << D1CXX
->getNumBases();
1624 // Check the base classes.
1625 for (CXXRecordDecl::base_class_iterator Base1
= D1CXX
->bases_begin(),
1626 BaseEnd1
= D1CXX
->bases_end(),
1627 Base2
= D2CXX
->bases_begin();
1628 Base1
!= BaseEnd1
; ++Base1
, ++Base2
) {
1629 if (!IsStructurallyEquivalent(Context
, Base1
->getType(),
1630 Base2
->getType())) {
1631 if (Context
.Complain
) {
1632 Context
.Diag2(D2
->getLocation(),
1633 Context
.getApplicableDiagnostic(
1634 diag::err_odr_tag_type_inconsistent
))
1635 << Context
.ToCtx
.getTypeDeclType(D2
);
1636 Context
.Diag2(Base2
->getBeginLoc(), diag::note_odr_base
)
1637 << Base2
->getType() << Base2
->getSourceRange();
1638 Context
.Diag1(Base1
->getBeginLoc(), diag::note_odr_base
)
1639 << Base1
->getType() << Base1
->getSourceRange();
1644 // Check virtual vs. non-virtual inheritance mismatch.
1645 if (Base1
->isVirtual() != Base2
->isVirtual()) {
1646 if (Context
.Complain
) {
1647 Context
.Diag2(D2
->getLocation(),
1648 Context
.getApplicableDiagnostic(
1649 diag::err_odr_tag_type_inconsistent
))
1650 << Context
.ToCtx
.getTypeDeclType(D2
);
1651 Context
.Diag2(Base2
->getBeginLoc(), diag::note_odr_virtual_base
)
1652 << Base2
->isVirtual() << Base2
->getSourceRange();
1653 Context
.Diag1(Base1
->getBeginLoc(), diag::note_odr_base
)
1654 << Base1
->isVirtual() << Base1
->getSourceRange();
1660 // Check the friends for consistency.
1661 CXXRecordDecl::friend_iterator Friend2
= D2CXX
->friend_begin(),
1662 Friend2End
= D2CXX
->friend_end();
1663 for (CXXRecordDecl::friend_iterator Friend1
= D1CXX
->friend_begin(),
1664 Friend1End
= D1CXX
->friend_end();
1665 Friend1
!= Friend1End
; ++Friend1
, ++Friend2
) {
1666 if (Friend2
== Friend2End
) {
1667 if (Context
.Complain
) {
1668 Context
.Diag2(D2
->getLocation(),
1669 Context
.getApplicableDiagnostic(
1670 diag::err_odr_tag_type_inconsistent
))
1671 << Context
.ToCtx
.getTypeDeclType(D2CXX
);
1672 Context
.Diag1((*Friend1
)->getFriendLoc(), diag::note_odr_friend
);
1673 Context
.Diag2(D2
->getLocation(), diag::note_odr_missing_friend
);
1678 if (!IsStructurallyEquivalent(Context
, *Friend1
, *Friend2
)) {
1679 if (Context
.Complain
) {
1680 Context
.Diag2(D2
->getLocation(),
1681 Context
.getApplicableDiagnostic(
1682 diag::err_odr_tag_type_inconsistent
))
1683 << Context
.ToCtx
.getTypeDeclType(D2CXX
);
1684 Context
.Diag1((*Friend1
)->getFriendLoc(), diag::note_odr_friend
);
1685 Context
.Diag2((*Friend2
)->getFriendLoc(), diag::note_odr_friend
);
1691 if (Friend2
!= Friend2End
) {
1692 if (Context
.Complain
) {
1693 Context
.Diag2(D2
->getLocation(),
1694 Context
.getApplicableDiagnostic(
1695 diag::err_odr_tag_type_inconsistent
))
1696 << Context
.ToCtx
.getTypeDeclType(D2
);
1697 Context
.Diag2((*Friend2
)->getFriendLoc(), diag::note_odr_friend
);
1698 Context
.Diag1(D1
->getLocation(), diag::note_odr_missing_friend
);
1702 } else if (D1CXX
->getNumBases() > 0) {
1703 if (Context
.Complain
) {
1704 Context
.Diag2(D2
->getLocation(),
1705 Context
.getApplicableDiagnostic(
1706 diag::err_odr_tag_type_inconsistent
))
1707 << Context
.ToCtx
.getTypeDeclType(D2
);
1708 const CXXBaseSpecifier
*Base1
= D1CXX
->bases_begin();
1709 Context
.Diag1(Base1
->getBeginLoc(), diag::note_odr_base
)
1710 << Base1
->getType() << Base1
->getSourceRange();
1711 Context
.Diag2(D2
->getLocation(), diag::note_odr_missing_base
);
1717 // Check the fields for consistency.
1718 QualType D2Type
= Context
.ToCtx
.getTypeDeclType(D2
);
1719 RecordDecl::field_iterator Field2
= D2
->field_begin(),
1720 Field2End
= D2
->field_end();
1721 for (RecordDecl::field_iterator Field1
= D1
->field_begin(),
1722 Field1End
= D1
->field_end();
1723 Field1
!= Field1End
; ++Field1
, ++Field2
) {
1724 if (Field2
== Field2End
) {
1725 if (Context
.Complain
) {
1726 Context
.Diag2(D2
->getLocation(),
1727 Context
.getApplicableDiagnostic(
1728 diag::err_odr_tag_type_inconsistent
))
1729 << Context
.ToCtx
.getTypeDeclType(D2
);
1730 Context
.Diag1(Field1
->getLocation(), diag::note_odr_field
)
1731 << Field1
->getDeclName() << Field1
->getType();
1732 Context
.Diag2(D2
->getLocation(), diag::note_odr_missing_field
);
1737 if (!IsStructurallyEquivalent(Context
, *Field1
, *Field2
, D2Type
))
1741 if (Field2
!= Field2End
) {
1742 if (Context
.Complain
) {
1743 Context
.Diag2(D2
->getLocation(), Context
.getApplicableDiagnostic(
1744 diag::err_odr_tag_type_inconsistent
))
1745 << Context
.ToCtx
.getTypeDeclType(D2
);
1746 Context
.Diag2(Field2
->getLocation(), diag::note_odr_field
)
1747 << Field2
->getDeclName() << Field2
->getType();
1748 Context
.Diag1(D1
->getLocation(), diag::note_odr_missing_field
);
1756 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1757 EnumConstantDecl
*D1
,
1758 EnumConstantDecl
*D2
) {
1759 const llvm::APSInt
&FromVal
= D1
->getInitVal();
1760 const llvm::APSInt
&ToVal
= D2
->getInitVal();
1761 if (FromVal
.isSigned() != ToVal
.isSigned())
1763 if (FromVal
.getBitWidth() != ToVal
.getBitWidth())
1765 if (FromVal
!= ToVal
)
1768 if (!IsStructurallyEquivalent(D1
->getIdentifier(), D2
->getIdentifier()))
1771 // Init expressions are the most expensive check, so do them last.
1772 return IsStructurallyEquivalent(Context
, D1
->getInitExpr(),
1776 /// Determine structural equivalence of two enums.
1777 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1778 EnumDecl
*D1
, EnumDecl
*D2
) {
1779 if (!NameIsStructurallyEquivalent(*D1
, *D2
)) {
1783 // Compare the definitions of these two enums. If either or both are
1784 // incomplete (i.e. forward declared), we assume that they are equivalent.
1785 D1
= D1
->getDefinition();
1786 D2
= D2
->getDefinition();
1790 EnumDecl::enumerator_iterator EC2
= D2
->enumerator_begin(),
1791 EC2End
= D2
->enumerator_end();
1792 for (EnumDecl::enumerator_iterator EC1
= D1
->enumerator_begin(),
1793 EC1End
= D1
->enumerator_end();
1794 EC1
!= EC1End
; ++EC1
, ++EC2
) {
1795 if (EC2
== EC2End
) {
1796 if (Context
.Complain
) {
1797 Context
.Diag2(D2
->getLocation(),
1798 Context
.getApplicableDiagnostic(
1799 diag::err_odr_tag_type_inconsistent
))
1800 << Context
.ToCtx
.getTypeDeclType(D2
);
1801 Context
.Diag1(EC1
->getLocation(), diag::note_odr_enumerator
)
1802 << EC1
->getDeclName() << toString(EC1
->getInitVal(), 10);
1803 Context
.Diag2(D2
->getLocation(), diag::note_odr_missing_enumerator
);
1808 llvm::APSInt Val1
= EC1
->getInitVal();
1809 llvm::APSInt Val2
= EC2
->getInitVal();
1810 if (!llvm::APSInt::isSameValue(Val1
, Val2
) ||
1811 !IsStructurallyEquivalent(EC1
->getIdentifier(), EC2
->getIdentifier())) {
1812 if (Context
.Complain
) {
1813 Context
.Diag2(D2
->getLocation(),
1814 Context
.getApplicableDiagnostic(
1815 diag::err_odr_tag_type_inconsistent
))
1816 << Context
.ToCtx
.getTypeDeclType(D2
);
1817 Context
.Diag2(EC2
->getLocation(), diag::note_odr_enumerator
)
1818 << EC2
->getDeclName() << toString(EC2
->getInitVal(), 10);
1819 Context
.Diag1(EC1
->getLocation(), diag::note_odr_enumerator
)
1820 << EC1
->getDeclName() << toString(EC1
->getInitVal(), 10);
1826 if (EC2
!= EC2End
) {
1827 if (Context
.Complain
) {
1828 Context
.Diag2(D2
->getLocation(), Context
.getApplicableDiagnostic(
1829 diag::err_odr_tag_type_inconsistent
))
1830 << Context
.ToCtx
.getTypeDeclType(D2
);
1831 Context
.Diag2(EC2
->getLocation(), diag::note_odr_enumerator
)
1832 << EC2
->getDeclName() << toString(EC2
->getInitVal(), 10);
1833 Context
.Diag1(D1
->getLocation(), diag::note_odr_missing_enumerator
);
1841 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1842 TemplateParameterList
*Params1
,
1843 TemplateParameterList
*Params2
) {
1844 if (Params1
->size() != Params2
->size()) {
1845 if (Context
.Complain
) {
1846 Context
.Diag2(Params2
->getTemplateLoc(),
1847 Context
.getApplicableDiagnostic(
1848 diag::err_odr_different_num_template_parameters
))
1849 << Params1
->size() << Params2
->size();
1850 Context
.Diag1(Params1
->getTemplateLoc(),
1851 diag::note_odr_template_parameter_list
);
1856 for (unsigned I
= 0, N
= Params1
->size(); I
!= N
; ++I
) {
1857 if (Params1
->getParam(I
)->getKind() != Params2
->getParam(I
)->getKind()) {
1858 if (Context
.Complain
) {
1859 Context
.Diag2(Params2
->getParam(I
)->getLocation(),
1860 Context
.getApplicableDiagnostic(
1861 diag::err_odr_different_template_parameter_kind
));
1862 Context
.Diag1(Params1
->getParam(I
)->getLocation(),
1863 diag::note_odr_template_parameter_here
);
1868 if (!IsStructurallyEquivalent(Context
, Params1
->getParam(I
),
1869 Params2
->getParam(I
)))
1876 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1877 TemplateTypeParmDecl
*D1
,
1878 TemplateTypeParmDecl
*D2
) {
1879 if (D1
->isParameterPack() != D2
->isParameterPack()) {
1880 if (Context
.Complain
) {
1881 Context
.Diag2(D2
->getLocation(),
1882 Context
.getApplicableDiagnostic(
1883 diag::err_odr_parameter_pack_non_pack
))
1884 << D2
->isParameterPack();
1885 Context
.Diag1(D1
->getLocation(), diag::note_odr_parameter_pack_non_pack
)
1886 << D1
->isParameterPack();
1894 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1895 NonTypeTemplateParmDecl
*D1
,
1896 NonTypeTemplateParmDecl
*D2
) {
1897 if (D1
->isParameterPack() != D2
->isParameterPack()) {
1898 if (Context
.Complain
) {
1899 Context
.Diag2(D2
->getLocation(),
1900 Context
.getApplicableDiagnostic(
1901 diag::err_odr_parameter_pack_non_pack
))
1902 << D2
->isParameterPack();
1903 Context
.Diag1(D1
->getLocation(), diag::note_odr_parameter_pack_non_pack
)
1904 << D1
->isParameterPack();
1910 if (!IsStructurallyEquivalent(Context
, D1
->getType(), D2
->getType())) {
1911 if (Context
.Complain
) {
1912 Context
.Diag2(D2
->getLocation(),
1913 Context
.getApplicableDiagnostic(
1914 diag::err_odr_non_type_parameter_type_inconsistent
))
1915 << D2
->getType() << D1
->getType();
1916 Context
.Diag1(D1
->getLocation(), diag::note_odr_value_here
)
1925 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1926 TemplateTemplateParmDecl
*D1
,
1927 TemplateTemplateParmDecl
*D2
) {
1928 if (D1
->isParameterPack() != D2
->isParameterPack()) {
1929 if (Context
.Complain
) {
1930 Context
.Diag2(D2
->getLocation(),
1931 Context
.getApplicableDiagnostic(
1932 diag::err_odr_parameter_pack_non_pack
))
1933 << D2
->isParameterPack();
1934 Context
.Diag1(D1
->getLocation(), diag::note_odr_parameter_pack_non_pack
)
1935 << D1
->isParameterPack();
1940 // Check template parameter lists.
1941 return IsStructurallyEquivalent(Context
, D1
->getTemplateParameters(),
1942 D2
->getTemplateParameters());
1945 static bool IsTemplateDeclCommonStructurallyEquivalent(
1946 StructuralEquivalenceContext
&Ctx
, TemplateDecl
*D1
, TemplateDecl
*D2
) {
1947 if (!IsStructurallyEquivalent(D1
->getIdentifier(), D2
->getIdentifier()))
1949 if (!D1
->getIdentifier()) // Special name
1950 if (D1
->getNameAsString() != D2
->getNameAsString())
1952 return IsStructurallyEquivalent(Ctx
, D1
->getTemplateParameters(),
1953 D2
->getTemplateParameters());
1956 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1957 ClassTemplateDecl
*D1
,
1958 ClassTemplateDecl
*D2
) {
1959 // Check template parameters.
1960 if (!IsTemplateDeclCommonStructurallyEquivalent(Context
, D1
, D2
))
1963 // Check the templated declaration.
1964 return IsStructurallyEquivalent(Context
, D1
->getTemplatedDecl(),
1965 D2
->getTemplatedDecl());
1968 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1969 FunctionTemplateDecl
*D1
,
1970 FunctionTemplateDecl
*D2
) {
1971 // Check template parameters.
1972 if (!IsTemplateDeclCommonStructurallyEquivalent(Context
, D1
, D2
))
1975 // Check the templated declaration.
1976 return IsStructurallyEquivalent(Context
, D1
->getTemplatedDecl()->getType(),
1977 D2
->getTemplatedDecl()->getType());
1980 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1983 // Check template parameters.
1984 if (!IsTemplateDeclCommonStructurallyEquivalent(Context
, D1
, D2
))
1987 // Check the constraint expression.
1988 return IsStructurallyEquivalent(Context
, D1
->getConstraintExpr(),
1989 D2
->getConstraintExpr());
1992 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1993 FriendDecl
*D1
, FriendDecl
*D2
) {
1994 if ((D1
->getFriendType() && D2
->getFriendDecl()) ||
1995 (D1
->getFriendDecl() && D2
->getFriendType())) {
1998 if (D1
->getFriendType() && D2
->getFriendType())
1999 return IsStructurallyEquivalent(Context
,
2000 D1
->getFriendType()->getType(),
2001 D2
->getFriendType()->getType());
2002 if (D1
->getFriendDecl() && D2
->getFriendDecl())
2003 return IsStructurallyEquivalent(Context
, D1
->getFriendDecl(),
2004 D2
->getFriendDecl());
2008 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
2009 TypedefNameDecl
*D1
, TypedefNameDecl
*D2
) {
2010 if (!IsStructurallyEquivalent(D1
->getIdentifier(), D2
->getIdentifier()))
2013 return IsStructurallyEquivalent(Context
, D1
->getUnderlyingType(),
2014 D2
->getUnderlyingType());
2017 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
2018 FunctionDecl
*D1
, FunctionDecl
*D2
) {
2019 if (!IsStructurallyEquivalent(D1
->getIdentifier(), D2
->getIdentifier()))
2022 if (D1
->isOverloadedOperator()) {
2023 if (!D2
->isOverloadedOperator())
2025 if (D1
->getOverloadedOperator() != D2
->getOverloadedOperator())
2029 // FIXME: Consider checking for function attributes as well.
2030 if (!IsStructurallyEquivalent(Context
, D1
->getType(), D2
->getType()))
2036 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
2037 ObjCIvarDecl
*D1
, ObjCIvarDecl
*D2
,
2038 QualType Owner2Type
) {
2039 if (D1
->getAccessControl() != D2
->getAccessControl())
2042 return IsStructurallyEquivalent(Context
, cast
<FieldDecl
>(D1
),
2043 cast
<FieldDecl
>(D2
), Owner2Type
);
2046 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
2047 ObjCIvarDecl
*D1
, ObjCIvarDecl
*D2
) {
2048 QualType Owner2Type
=
2049 Context
.ToCtx
.getObjCInterfaceType(D2
->getContainingInterface());
2050 return IsStructurallyEquivalent(Context
, D1
, D2
, Owner2Type
);
2053 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
2054 ObjCMethodDecl
*Method1
,
2055 ObjCMethodDecl
*Method2
) {
2056 bool PropertiesEqual
=
2057 Method1
->isInstanceMethod() == Method2
->isInstanceMethod() &&
2058 Method1
->isVariadic() == Method2
->isVariadic() &&
2059 Method1
->isDirectMethod() == Method2
->isDirectMethod();
2060 if (!PropertiesEqual
)
2063 // Compare selector slot names.
2064 Selector Selector1
= Method1
->getSelector(),
2065 Selector2
= Method2
->getSelector();
2066 unsigned NumArgs
= Selector1
.getNumArgs();
2067 if (NumArgs
!= Selector2
.getNumArgs())
2069 // Compare all selector slots. For selectors with arguments it means all arg
2070 // slots. And if there are no arguments, compare the first-and-only slot.
2071 unsigned SlotsToCheck
= NumArgs
> 0 ? NumArgs
: 1;
2072 for (unsigned I
= 0; I
< SlotsToCheck
; ++I
) {
2073 if (!IsStructurallyEquivalent(Selector1
.getIdentifierInfoForSlot(I
),
2074 Selector2
.getIdentifierInfoForSlot(I
)))
2079 if (!IsStructurallyEquivalent(Context
, Method1
->getReturnType(),
2080 Method2
->getReturnType()))
2083 Method1
->param_size() == Method2
->param_size() &&
2084 "Same number of arguments should be already enforced in Selector checks");
2085 for (ObjCMethodDecl::param_type_iterator
2086 ParamT1
= Method1
->param_type_begin(),
2087 ParamT1End
= Method1
->param_type_end(),
2088 ParamT2
= Method2
->param_type_begin(),
2089 ParamT2End
= Method2
->param_type_end();
2090 (ParamT1
!= ParamT1End
) && (ParamT2
!= ParamT2End
);
2091 ++ParamT1
, ++ParamT2
) {
2092 if (!IsStructurallyEquivalent(Context
, *ParamT1
, *ParamT2
))
2099 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
2100 ObjCCategoryDecl
*D1
,
2101 ObjCCategoryDecl
*D2
) {
2102 if (!IsStructurallyEquivalent(D1
->getIdentifier(), D2
->getIdentifier()))
2105 const ObjCInterfaceDecl
*Intf1
= D1
->getClassInterface(),
2106 *Intf2
= D2
->getClassInterface();
2107 if ((!Intf1
|| !Intf2
) && (Intf1
!= Intf2
))
2111 !IsStructurallyEquivalent(Intf1
->getIdentifier(), Intf2
->getIdentifier()))
2114 // Compare protocols.
2115 ObjCCategoryDecl::protocol_iterator Protocol2
= D2
->protocol_begin(),
2116 Protocol2End
= D2
->protocol_end();
2117 for (ObjCCategoryDecl::protocol_iterator Protocol1
= D1
->protocol_begin(),
2118 Protocol1End
= D1
->protocol_end();
2119 Protocol1
!= Protocol1End
; ++Protocol1
, ++Protocol2
) {
2120 if (Protocol2
== Protocol2End
)
2122 if (!IsStructurallyEquivalent((*Protocol1
)->getIdentifier(),
2123 (*Protocol2
)->getIdentifier()))
2126 if (Protocol2
!= Protocol2End
)
2131 Intf2
? Context
.ToCtx
.getObjCInterfaceType(Intf2
) : QualType();
2132 ObjCCategoryDecl::ivar_iterator Ivar2
= D2
->ivar_begin(),
2133 Ivar2End
= D2
->ivar_end();
2134 for (ObjCCategoryDecl::ivar_iterator Ivar1
= D1
->ivar_begin(),
2135 Ivar1End
= D1
->ivar_end();
2136 Ivar1
!= Ivar1End
; ++Ivar1
, ++Ivar2
) {
2137 if (Ivar2
== Ivar2End
)
2139 if (!IsStructurallyEquivalent(Context
, *Ivar1
, *Ivar2
, D2Type
))
2142 if (Ivar2
!= Ivar2End
)
2146 ObjCCategoryDecl::method_iterator Method2
= D2
->meth_begin(),
2147 Method2End
= D2
->meth_end();
2148 for (ObjCCategoryDecl::method_iterator Method1
= D1
->meth_begin(),
2149 Method1End
= D1
->meth_end();
2150 Method1
!= Method1End
; ++Method1
, ++Method2
) {
2151 if (Method2
== Method2End
)
2153 if (!IsStructurallyEquivalent(Context
, *Method1
, *Method2
))
2156 if (Method2
!= Method2End
)
2162 /// Determine structural equivalence of two declarations.
2163 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
2164 Decl
*D1
, Decl
*D2
) {
2165 // FIXME: Check for known structural equivalences via a callback of some sort.
2167 D1
= D1
->getCanonicalDecl();
2168 D2
= D2
->getCanonicalDecl();
2169 std::pair
<Decl
*, Decl
*> P
{D1
, D2
};
2171 // Check whether we already know that these two declarations are not
2172 // structurally equivalent.
2173 if (Context
.NonEquivalentDecls
.count(P
))
2176 // Check if a check for these declarations is already pending.
2177 // If yes D1 and D2 will be checked later (from DeclsToCheck),
2178 // or these are already checked (and equivalent).
2179 bool Inserted
= Context
.VisitedDecls
.insert(P
).second
;
2183 Context
.DeclsToCheck
.push(P
);
2188 DiagnosticBuilder
StructuralEquivalenceContext::Diag1(SourceLocation Loc
,
2190 assert(Complain
&& "Not allowed to complain");
2192 FromCtx
.getDiagnostics().notePriorDiagnosticFrom(ToCtx
.getDiagnostics());
2193 LastDiagFromC2
= false;
2194 return FromCtx
.getDiagnostics().Report(Loc
, DiagID
);
2197 DiagnosticBuilder
StructuralEquivalenceContext::Diag2(SourceLocation Loc
,
2199 assert(Complain
&& "Not allowed to complain");
2200 if (!LastDiagFromC2
)
2201 ToCtx
.getDiagnostics().notePriorDiagnosticFrom(FromCtx
.getDiagnostics());
2202 LastDiagFromC2
= true;
2203 return ToCtx
.getDiagnostics().Report(Loc
, DiagID
);
2206 std::optional
<unsigned>
2207 StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl
*Anon
) {
2208 ASTContext
&Context
= Anon
->getASTContext();
2209 QualType AnonTy
= Context
.getRecordType(Anon
);
2211 const auto *Owner
= dyn_cast
<RecordDecl
>(Anon
->getDeclContext());
2213 return std::nullopt
;
2216 for (const auto *D
: Owner
->noload_decls()) {
2217 const auto *F
= dyn_cast
<FieldDecl
>(D
);
2221 if (F
->isAnonymousStructOrUnion()) {
2222 if (Context
.hasSameType(F
->getType(), AnonTy
))
2228 // If the field looks like this:
2229 // struct { ... } A;
2230 QualType FieldType
= F
->getType();
2231 // In case of nested structs.
2232 while (const auto *ElabType
= dyn_cast
<ElaboratedType
>(FieldType
))
2233 FieldType
= ElabType
->getNamedType();
2235 if (const auto *RecType
= dyn_cast
<RecordType
>(FieldType
)) {
2236 const RecordDecl
*RecDecl
= RecType
->getDecl();
2237 if (RecDecl
->getDeclContext() == Owner
&& !RecDecl
->getIdentifier()) {
2238 if (Context
.hasSameType(FieldType
, AnonTy
))
2249 unsigned StructuralEquivalenceContext::getApplicableDiagnostic(
2250 unsigned ErrorDiagnostic
) {
2251 if (ErrorOnTagTypeMismatch
)
2252 return ErrorDiagnostic
;
2254 switch (ErrorDiagnostic
) {
2255 case diag::err_odr_variable_type_inconsistent
:
2256 return diag::warn_odr_variable_type_inconsistent
;
2257 case diag::err_odr_variable_multiple_def
:
2258 return diag::warn_odr_variable_multiple_def
;
2259 case diag::err_odr_function_type_inconsistent
:
2260 return diag::warn_odr_function_type_inconsistent
;
2261 case diag::err_odr_tag_type_inconsistent
:
2262 return diag::warn_odr_tag_type_inconsistent
;
2263 case diag::err_odr_field_type_inconsistent
:
2264 return diag::warn_odr_field_type_inconsistent
;
2265 case diag::err_odr_ivar_type_inconsistent
:
2266 return diag::warn_odr_ivar_type_inconsistent
;
2267 case diag::err_odr_objc_superclass_inconsistent
:
2268 return diag::warn_odr_objc_superclass_inconsistent
;
2269 case diag::err_odr_objc_method_result_type_inconsistent
:
2270 return diag::warn_odr_objc_method_result_type_inconsistent
;
2271 case diag::err_odr_objc_method_num_params_inconsistent
:
2272 return diag::warn_odr_objc_method_num_params_inconsistent
;
2273 case diag::err_odr_objc_method_param_type_inconsistent
:
2274 return diag::warn_odr_objc_method_param_type_inconsistent
;
2275 case diag::err_odr_objc_method_variadic_inconsistent
:
2276 return diag::warn_odr_objc_method_variadic_inconsistent
;
2277 case diag::err_odr_objc_property_type_inconsistent
:
2278 return diag::warn_odr_objc_property_type_inconsistent
;
2279 case diag::err_odr_objc_property_impl_kind_inconsistent
:
2280 return diag::warn_odr_objc_property_impl_kind_inconsistent
;
2281 case diag::err_odr_objc_synthesize_ivar_inconsistent
:
2282 return diag::warn_odr_objc_synthesize_ivar_inconsistent
;
2283 case diag::err_odr_different_num_template_parameters
:
2284 return diag::warn_odr_different_num_template_parameters
;
2285 case diag::err_odr_different_template_parameter_kind
:
2286 return diag::warn_odr_different_template_parameter_kind
;
2287 case diag::err_odr_parameter_pack_non_pack
:
2288 return diag::warn_odr_parameter_pack_non_pack
;
2289 case diag::err_odr_non_type_parameter_type_inconsistent
:
2290 return diag::warn_odr_non_type_parameter_type_inconsistent
;
2292 llvm_unreachable("Diagnostic kind not handled in preceding switch");
2295 bool StructuralEquivalenceContext::IsEquivalent(Decl
*D1
, Decl
*D2
) {
2297 // Ensure that the implementation functions (all static functions in this TU)
2298 // never call the public ASTStructuralEquivalence::IsEquivalent() functions,
2299 // because that will wreak havoc the internal state (DeclsToCheck and
2300 // VisitedDecls members) and can cause faulty behaviour.
2301 // In other words: Do not start a graph search from a new node with the
2302 // internal data of another search in progress.
2303 // FIXME: Better encapsulation and separation of internal and public
2305 assert(DeclsToCheck
.empty());
2306 assert(VisitedDecls
.empty());
2308 if (!::IsStructurallyEquivalent(*this, D1
, D2
))
2314 bool StructuralEquivalenceContext::IsEquivalent(QualType T1
, QualType T2
) {
2315 assert(DeclsToCheck
.empty());
2316 assert(VisitedDecls
.empty());
2317 if (!::IsStructurallyEquivalent(*this, T1
, T2
))
2323 bool StructuralEquivalenceContext::IsEquivalent(Stmt
*S1
, Stmt
*S2
) {
2324 assert(DeclsToCheck
.empty());
2325 assert(VisitedDecls
.empty());
2326 if (!::IsStructurallyEquivalent(*this, S1
, S2
))
2332 bool StructuralEquivalenceContext::CheckCommonEquivalence(Decl
*D1
, Decl
*D2
) {
2333 // Check for equivalent described template.
2334 TemplateDecl
*Template1
= D1
->getDescribedTemplate();
2335 TemplateDecl
*Template2
= D2
->getDescribedTemplate();
2336 if ((Template1
!= nullptr) != (Template2
!= nullptr))
2338 if (Template1
&& !IsStructurallyEquivalent(*this, Template1
, Template2
))
2341 // FIXME: Move check for identifier names into this function.
2346 bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
2347 Decl
*D1
, Decl
*D2
) {
2350 if (D1
->getKind() != D2
->getKind())
2353 // Cast the Decls to their actual subclass so that the right overload of
2354 // IsStructurallyEquivalent is called.
2355 switch (D1
->getKind()) {
2356 #define ABSTRACT_DECL(DECL)
2357 #define DECL(DERIVED, BASE) \
2358 case Decl::Kind::DERIVED: \
2359 return ::IsStructurallyEquivalent(*this, static_cast<DERIVED##Decl *>(D1), \
2360 static_cast<DERIVED##Decl *>(D2));
2361 #include "clang/AST/DeclNodes.inc"
2366 bool StructuralEquivalenceContext::Finish() {
2367 while (!DeclsToCheck
.empty()) {
2368 // Check the next declaration.
2369 std::pair
<Decl
*, Decl
*> P
= DeclsToCheck
.front();
2373 Decl
*D2
= P
.second
;
2376 CheckCommonEquivalence(D1
, D2
) && CheckKindSpecificEquivalence(D1
, D2
);
2379 // Note that these two declarations are not equivalent (and we already
2381 NonEquivalentDecls
.insert(P
);