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/None.h"
88 #include "llvm/ADT/Optional.h"
89 #include "llvm/ADT/StringExtras.h"
90 #include "llvm/Support/Casting.h"
91 #include "llvm/Support/Compiler.h"
92 #include "llvm/Support/ErrorHandling.h"
96 using namespace clang
;
98 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
99 QualType T1
, QualType T2
);
100 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
102 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
103 const TemplateArgument
&Arg1
,
104 const TemplateArgument
&Arg2
);
105 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
106 NestedNameSpecifier
*NNS1
,
107 NestedNameSpecifier
*NNS2
);
108 static bool IsStructurallyEquivalent(const IdentifierInfo
*Name1
,
109 const IdentifierInfo
*Name2
);
111 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
112 const DeclarationName Name1
,
113 const DeclarationName Name2
) {
114 if (Name1
.getNameKind() != Name2
.getNameKind())
117 switch (Name1
.getNameKind()) {
119 case DeclarationName::Identifier
:
120 return IsStructurallyEquivalent(Name1
.getAsIdentifierInfo(),
121 Name2
.getAsIdentifierInfo());
123 case DeclarationName::CXXConstructorName
:
124 case DeclarationName::CXXDestructorName
:
125 case DeclarationName::CXXConversionFunctionName
:
126 return IsStructurallyEquivalent(Context
, Name1
.getCXXNameType(),
127 Name2
.getCXXNameType());
129 case DeclarationName::CXXDeductionGuideName
: {
130 if (!IsStructurallyEquivalent(
131 Context
, Name1
.getCXXDeductionGuideTemplate()->getDeclName(),
132 Name2
.getCXXDeductionGuideTemplate()->getDeclName()))
134 return IsStructurallyEquivalent(Context
,
135 Name1
.getCXXDeductionGuideTemplate(),
136 Name2
.getCXXDeductionGuideTemplate());
139 case DeclarationName::CXXOperatorName
:
140 return Name1
.getCXXOverloadedOperator() == Name2
.getCXXOverloadedOperator();
142 case DeclarationName::CXXLiteralOperatorName
:
143 return IsStructurallyEquivalent(Name1
.getCXXLiteralIdentifier(),
144 Name2
.getCXXLiteralIdentifier());
146 case DeclarationName::CXXUsingDirective
:
147 return true; // FIXME When do we consider two using directives equal?
149 case DeclarationName::ObjCZeroArgSelector
:
150 case DeclarationName::ObjCOneArgSelector
:
151 case DeclarationName::ObjCMultiArgSelector
:
152 return true; // FIXME
155 llvm_unreachable("Unhandled kind of DeclarationName");
160 /// Encapsulates Stmt comparison logic.
162 StructuralEquivalenceContext
&Context
;
164 // IsStmtEquivalent overloads. Each overload compares a specific statement
165 // and only has to compare the data that is specific to the specific statement
166 // class. Should only be called from TraverseStmt.
168 bool IsStmtEquivalent(const AddrLabelExpr
*E1
, const AddrLabelExpr
*E2
) {
169 return IsStructurallyEquivalent(Context
, E1
->getLabel(), E2
->getLabel());
172 bool IsStmtEquivalent(const AtomicExpr
*E1
, const AtomicExpr
*E2
) {
173 return E1
->getOp() == E2
->getOp();
176 bool IsStmtEquivalent(const BinaryOperator
*E1
, const BinaryOperator
*E2
) {
177 return E1
->getOpcode() == E2
->getOpcode();
180 bool IsStmtEquivalent(const CallExpr
*E1
, const CallExpr
*E2
) {
181 // FIXME: IsStructurallyEquivalent requires non-const Decls.
182 Decl
*Callee1
= const_cast<Decl
*>(E1
->getCalleeDecl());
183 Decl
*Callee2
= const_cast<Decl
*>(E2
->getCalleeDecl());
185 // Compare whether both calls know their callee.
186 if (static_cast<bool>(Callee1
) != static_cast<bool>(Callee2
))
189 // Both calls have no callee, so nothing to do.
190 if (!static_cast<bool>(Callee1
))
194 return IsStructurallyEquivalent(Context
, Callee1
, Callee2
);
197 bool IsStmtEquivalent(const CharacterLiteral
*E1
,
198 const CharacterLiteral
*E2
) {
199 return E1
->getValue() == E2
->getValue() && E1
->getKind() == E2
->getKind();
202 bool IsStmtEquivalent(const ChooseExpr
*E1
, const ChooseExpr
*E2
) {
203 return true; // Semantics only depend on children.
206 bool IsStmtEquivalent(const CompoundStmt
*E1
, const CompoundStmt
*E2
) {
207 // Number of children is actually checked by the generic children comparison
208 // code, but a CompoundStmt is one of the few statements where the number of
209 // children frequently differs and the number of statements is also always
210 // precomputed. Directly comparing the number of children here is thus
211 // just an optimization.
212 return E1
->size() == E2
->size();
215 bool IsStmtEquivalent(const DependentScopeDeclRefExpr
*DE1
,
216 const DependentScopeDeclRefExpr
*DE2
) {
217 if (!IsStructurallyEquivalent(Context
, DE1
->getDeclName(),
220 return IsStructurallyEquivalent(Context
, DE1
->getQualifier(),
221 DE2
->getQualifier());
224 bool IsStmtEquivalent(const Expr
*E1
, const Expr
*E2
) {
225 return IsStructurallyEquivalent(Context
, E1
->getType(), E2
->getType());
228 bool IsStmtEquivalent(const ExpressionTraitExpr
*E1
,
229 const ExpressionTraitExpr
*E2
) {
230 return E1
->getTrait() == E2
->getTrait() && E1
->getValue() == E2
->getValue();
233 bool IsStmtEquivalent(const FloatingLiteral
*E1
, const FloatingLiteral
*E2
) {
234 return E1
->isExact() == E2
->isExact() && E1
->getValue() == E2
->getValue();
237 bool IsStmtEquivalent(const GenericSelectionExpr
*E1
,
238 const GenericSelectionExpr
*E2
) {
239 for (auto Pair
: zip_longest(E1
->getAssocTypeSourceInfos(),
240 E2
->getAssocTypeSourceInfos())) {
241 Optional
<TypeSourceInfo
*> Child1
= std::get
<0>(Pair
);
242 Optional
<TypeSourceInfo
*> Child2
= std::get
<1>(Pair
);
243 // Skip this case if there are a different number of associated types.
244 if (!Child1
|| !Child2
)
247 if (!IsStructurallyEquivalent(Context
, (*Child1
)->getType(),
248 (*Child2
)->getType()))
255 bool IsStmtEquivalent(const ImplicitCastExpr
*CastE1
,
256 const ImplicitCastExpr
*CastE2
) {
257 return IsStructurallyEquivalent(Context
, CastE1
->getType(),
261 bool IsStmtEquivalent(const IntegerLiteral
*E1
, const IntegerLiteral
*E2
) {
262 return E1
->getValue() == E2
->getValue();
265 bool IsStmtEquivalent(const MemberExpr
*E1
, const MemberExpr
*E2
) {
266 return IsStructurallyEquivalent(Context
, E1
->getFoundDecl(),
270 bool IsStmtEquivalent(const ObjCStringLiteral
*E1
,
271 const ObjCStringLiteral
*E2
) {
272 // Just wraps a StringLiteral child.
276 bool IsStmtEquivalent(const Stmt
*S1
, const Stmt
*S2
) { return true; }
278 bool IsStmtEquivalent(const SourceLocExpr
*E1
, const SourceLocExpr
*E2
) {
279 return E1
->getIdentKind() == E2
->getIdentKind();
282 bool IsStmtEquivalent(const StmtExpr
*E1
, const StmtExpr
*E2
) {
283 return E1
->getTemplateDepth() == E2
->getTemplateDepth();
286 bool IsStmtEquivalent(const StringLiteral
*E1
, const StringLiteral
*E2
) {
287 return E1
->getBytes() == E2
->getBytes();
290 bool IsStmtEquivalent(const SubstNonTypeTemplateParmExpr
*E1
,
291 const SubstNonTypeTemplateParmExpr
*E2
) {
292 return IsStructurallyEquivalent(Context
, E1
->getParameter(),
296 bool IsStmtEquivalent(const SubstNonTypeTemplateParmPackExpr
*E1
,
297 const SubstNonTypeTemplateParmPackExpr
*E2
) {
298 return IsStructurallyEquivalent(Context
, E1
->getArgumentPack(),
299 E2
->getArgumentPack());
302 bool IsStmtEquivalent(const TypeTraitExpr
*E1
, const TypeTraitExpr
*E2
) {
303 if (E1
->getTrait() != E2
->getTrait())
306 for (auto Pair
: zip_longest(E1
->getArgs(), E2
->getArgs())) {
307 Optional
<TypeSourceInfo
*> Child1
= std::get
<0>(Pair
);
308 Optional
<TypeSourceInfo
*> Child2
= std::get
<1>(Pair
);
309 // Different number of args.
310 if (!Child1
|| !Child2
)
313 if (!IsStructurallyEquivalent(Context
, (*Child1
)->getType(),
314 (*Child2
)->getType()))
320 bool IsStmtEquivalent(const UnaryExprOrTypeTraitExpr
*E1
,
321 const UnaryExprOrTypeTraitExpr
*E2
) {
322 if (E1
->getKind() != E2
->getKind())
324 return IsStructurallyEquivalent(Context
, E1
->getTypeOfArgument(),
325 E2
->getTypeOfArgument());
328 bool IsStmtEquivalent(const UnaryOperator
*E1
, const UnaryOperator
*E2
) {
329 return E1
->getOpcode() == E2
->getOpcode();
332 bool IsStmtEquivalent(const VAArgExpr
*E1
, const VAArgExpr
*E2
) {
333 // Semantics only depend on children.
337 /// End point of the traversal chain.
338 bool TraverseStmt(const Stmt
*S1
, const Stmt
*S2
) { return true; }
340 // Create traversal methods that traverse the class hierarchy and return
341 // the accumulated result of the comparison. Each TraverseStmt overload
342 // calls the TraverseStmt overload of the parent class. For example,
343 // the TraverseStmt overload for 'BinaryOperator' calls the TraverseStmt
344 // overload of 'Expr' which then calls the overload for 'Stmt'.
345 #define STMT(CLASS, PARENT) \
346 bool TraverseStmt(const CLASS *S1, const CLASS *S2) { \
347 if (!TraverseStmt(static_cast<const PARENT *>(S1), \
348 static_cast<const PARENT *>(S2))) \
350 return IsStmtEquivalent(S1, S2); \
352 #include "clang/AST/StmtNodes.inc"
355 StmtComparer(StructuralEquivalenceContext
&C
) : Context(C
) {}
357 /// Determine whether two statements are equivalent. The statements have to
358 /// be of the same kind. The children of the statements and their properties
359 /// are not compared by this function.
360 bool IsEquivalent(const Stmt
*S1
, const Stmt
*S2
) {
361 if (S1
->getStmtClass() != S2
->getStmtClass())
364 // Each TraverseStmt walks the class hierarchy from the leaf class to
365 // the root class 'Stmt' (e.g. 'BinaryOperator' -> 'Expr' -> 'Stmt'). Cast
366 // the Stmt we have here to its specific subclass so that we call the
367 // overload that walks the whole class hierarchy from leaf to root (e.g.,
368 // cast to 'BinaryOperator' so that 'Expr' and 'Stmt' is traversed).
369 switch (S1
->getStmtClass()) {
370 case Stmt::NoStmtClass
:
371 llvm_unreachable("Can't traverse NoStmtClass");
372 #define STMT(CLASS, PARENT) \
373 case Stmt::StmtClass::CLASS##Class: \
374 return TraverseStmt(static_cast<const CLASS *>(S1), \
375 static_cast<const CLASS *>(S2));
376 #define ABSTRACT_STMT(S)
377 #include "clang/AST/StmtNodes.inc"
379 llvm_unreachable("Invalid statement kind");
384 /// Determine structural equivalence of two statements.
385 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
386 const Stmt
*S1
, const Stmt
*S2
) {
390 // Compare the statements itself.
391 StmtComparer
Comparer(Context
);
392 if (!Comparer
.IsEquivalent(S1
, S2
))
395 // Iterate over the children of both statements and also compare them.
396 for (auto Pair
: zip_longest(S1
->children(), S2
->children())) {
397 Optional
<const Stmt
*> Child1
= std::get
<0>(Pair
);
398 Optional
<const Stmt
*> Child2
= std::get
<1>(Pair
);
399 // One of the statements has a different amount of children than the other,
400 // so the statements can't be equivalent.
401 if (!Child1
|| !Child2
)
403 if (!IsStructurallyEquivalent(Context
, *Child1
, *Child2
))
409 /// Determine whether two identifiers are equivalent.
410 static bool IsStructurallyEquivalent(const IdentifierInfo
*Name1
,
411 const IdentifierInfo
*Name2
) {
412 if (!Name1
|| !Name2
)
413 return Name1
== Name2
;
415 return Name1
->getName() == Name2
->getName();
418 /// Determine whether two nested-name-specifiers are equivalent.
419 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
420 NestedNameSpecifier
*NNS1
,
421 NestedNameSpecifier
*NNS2
) {
422 if (NNS1
->getKind() != NNS2
->getKind())
425 NestedNameSpecifier
*Prefix1
= NNS1
->getPrefix(),
426 *Prefix2
= NNS2
->getPrefix();
427 if ((bool)Prefix1
!= (bool)Prefix2
)
431 if (!IsStructurallyEquivalent(Context
, Prefix1
, Prefix2
))
434 switch (NNS1
->getKind()) {
435 case NestedNameSpecifier::Identifier
:
436 return IsStructurallyEquivalent(NNS1
->getAsIdentifier(),
437 NNS2
->getAsIdentifier());
438 case NestedNameSpecifier::Namespace
:
439 return IsStructurallyEquivalent(Context
, NNS1
->getAsNamespace(),
440 NNS2
->getAsNamespace());
441 case NestedNameSpecifier::NamespaceAlias
:
442 return IsStructurallyEquivalent(Context
, NNS1
->getAsNamespaceAlias(),
443 NNS2
->getAsNamespaceAlias());
444 case NestedNameSpecifier::TypeSpec
:
445 case NestedNameSpecifier::TypeSpecWithTemplate
:
446 return IsStructurallyEquivalent(Context
, QualType(NNS1
->getAsType(), 0),
447 QualType(NNS2
->getAsType(), 0));
448 case NestedNameSpecifier::Global
:
450 case NestedNameSpecifier::Super
:
451 return IsStructurallyEquivalent(Context
, NNS1
->getAsRecordDecl(),
452 NNS2
->getAsRecordDecl());
457 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
458 const TemplateName
&N1
,
459 const TemplateName
&N2
) {
460 TemplateDecl
*TemplateDeclN1
= N1
.getAsTemplateDecl();
461 TemplateDecl
*TemplateDeclN2
= N2
.getAsTemplateDecl();
462 if (TemplateDeclN1
&& TemplateDeclN2
) {
463 if (!IsStructurallyEquivalent(Context
, TemplateDeclN1
, TemplateDeclN2
))
465 // If the kind is different we compare only the template decl.
466 if (N1
.getKind() != N2
.getKind())
468 } else if (TemplateDeclN1
|| TemplateDeclN2
)
470 else if (N1
.getKind() != N2
.getKind())
473 // Check for special case incompatibilities.
474 switch (N1
.getKind()) {
476 case TemplateName::OverloadedTemplate
: {
477 OverloadedTemplateStorage
*OS1
= N1
.getAsOverloadedTemplate(),
478 *OS2
= N2
.getAsOverloadedTemplate();
479 OverloadedTemplateStorage::iterator I1
= OS1
->begin(), I2
= OS2
->begin(),
480 E1
= OS1
->end(), E2
= OS2
->end();
481 for (; I1
!= E1
&& I2
!= E2
; ++I1
, ++I2
)
482 if (!IsStructurallyEquivalent(Context
, *I1
, *I2
))
484 return I1
== E1
&& I2
== E2
;
487 case TemplateName::AssumedTemplate
: {
488 AssumedTemplateStorage
*TN1
= N1
.getAsAssumedTemplateName(),
489 *TN2
= N1
.getAsAssumedTemplateName();
490 return TN1
->getDeclName() == TN2
->getDeclName();
493 case TemplateName::DependentTemplate
: {
494 DependentTemplateName
*DN1
= N1
.getAsDependentTemplateName(),
495 *DN2
= N2
.getAsDependentTemplateName();
496 if (!IsStructurallyEquivalent(Context
, DN1
->getQualifier(),
497 DN2
->getQualifier()))
499 if (DN1
->isIdentifier() && DN2
->isIdentifier())
500 return IsStructurallyEquivalent(DN1
->getIdentifier(),
501 DN2
->getIdentifier());
502 else if (DN1
->isOverloadedOperator() && DN2
->isOverloadedOperator())
503 return DN1
->getOperator() == DN2
->getOperator();
507 case TemplateName::SubstTemplateTemplateParmPack
: {
508 SubstTemplateTemplateParmPackStorage
509 *P1
= N1
.getAsSubstTemplateTemplateParmPack(),
510 *P2
= N2
.getAsSubstTemplateTemplateParmPack();
511 return IsStructurallyEquivalent(Context
, P1
->getArgumentPack(),
512 P2
->getArgumentPack()) &&
513 IsStructurallyEquivalent(Context
, P1
->getParameterPack(),
514 P2
->getParameterPack());
517 case TemplateName::Template
:
518 case TemplateName::QualifiedTemplate
:
519 case TemplateName::SubstTemplateTemplateParm
:
520 case TemplateName::UsingTemplate
:
521 // It is sufficient to check value of getAsTemplateDecl.
529 /// Determine whether two template arguments are equivalent.
530 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
531 const TemplateArgument
&Arg1
,
532 const TemplateArgument
&Arg2
) {
533 if (Arg1
.getKind() != Arg2
.getKind())
536 switch (Arg1
.getKind()) {
537 case TemplateArgument::Null
:
540 case TemplateArgument::Type
:
541 return IsStructurallyEquivalent(Context
, Arg1
.getAsType(), Arg2
.getAsType());
543 case TemplateArgument::Integral
:
544 if (!IsStructurallyEquivalent(Context
, Arg1
.getIntegralType(),
545 Arg2
.getIntegralType()))
548 return llvm::APSInt::isSameValue(Arg1
.getAsIntegral(),
549 Arg2
.getAsIntegral());
551 case TemplateArgument::Declaration
:
552 return IsStructurallyEquivalent(Context
, Arg1
.getAsDecl(), Arg2
.getAsDecl());
554 case TemplateArgument::NullPtr
:
555 return true; // FIXME: Is this correct?
557 case TemplateArgument::Template
:
558 return IsStructurallyEquivalent(Context
, Arg1
.getAsTemplate(),
559 Arg2
.getAsTemplate());
561 case TemplateArgument::TemplateExpansion
:
562 return IsStructurallyEquivalent(Context
,
563 Arg1
.getAsTemplateOrTemplatePattern(),
564 Arg2
.getAsTemplateOrTemplatePattern());
566 case TemplateArgument::Expression
:
567 return IsStructurallyEquivalent(Context
, Arg1
.getAsExpr(),
570 case TemplateArgument::Pack
:
571 if (Arg1
.pack_size() != Arg2
.pack_size())
574 for (unsigned I
= 0, N
= Arg1
.pack_size(); I
!= N
; ++I
)
575 if (!IsStructurallyEquivalent(Context
, Arg1
.pack_begin()[I
],
576 Arg2
.pack_begin()[I
]))
582 llvm_unreachable("Invalid template argument kind");
585 /// Determine structural equivalence for the common part of array
587 static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
588 const ArrayType
*Array1
,
589 const ArrayType
*Array2
) {
590 if (!IsStructurallyEquivalent(Context
, Array1
->getElementType(),
591 Array2
->getElementType()))
593 if (Array1
->getSizeModifier() != Array2
->getSizeModifier())
595 if (Array1
->getIndexTypeQualifiers() != Array2
->getIndexTypeQualifiers())
601 /// Determine structural equivalence based on the ExtInfo of functions. This
602 /// is inspired by ASTContext::mergeFunctionTypes(), we compare calling
603 /// conventions bits but must not compare some other bits.
604 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
605 FunctionType::ExtInfo EI1
,
606 FunctionType::ExtInfo EI2
) {
607 // Compatible functions must have compatible calling conventions.
608 if (EI1
.getCC() != EI2
.getCC())
611 // Regparm is part of the calling convention.
612 if (EI1
.getHasRegParm() != EI2
.getHasRegParm())
614 if (EI1
.getRegParm() != EI2
.getRegParm())
617 if (EI1
.getProducesResult() != EI2
.getProducesResult())
619 if (EI1
.getNoCallerSavedRegs() != EI2
.getNoCallerSavedRegs())
621 if (EI1
.getNoCfCheck() != EI2
.getNoCfCheck())
627 /// Check the equivalence of exception specifications.
628 static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext
&Context
,
629 const FunctionProtoType
*Proto1
,
630 const FunctionProtoType
*Proto2
) {
632 auto Spec1
= Proto1
->getExceptionSpecType();
633 auto Spec2
= Proto2
->getExceptionSpecType();
635 if (isUnresolvedExceptionSpec(Spec1
) || isUnresolvedExceptionSpec(Spec2
))
640 if (Spec1
== EST_Dynamic
) {
641 if (Proto1
->getNumExceptions() != Proto2
->getNumExceptions())
643 for (unsigned I
= 0, N
= Proto1
->getNumExceptions(); I
!= N
; ++I
) {
644 if (!IsStructurallyEquivalent(Context
, Proto1
->getExceptionType(I
),
645 Proto2
->getExceptionType(I
)))
648 } else if (isComputedNoexcept(Spec1
)) {
649 if (!IsStructurallyEquivalent(Context
, Proto1
->getNoexceptExpr(),
650 Proto2
->getNoexceptExpr()))
657 /// Determine structural equivalence of two types.
658 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
659 QualType T1
, QualType T2
) {
660 if (T1
.isNull() || T2
.isNull())
661 return T1
.isNull() && T2
.isNull();
663 QualType OrigT1
= T1
;
664 QualType OrigT2
= T2
;
666 if (!Context
.StrictTypeSpelling
) {
667 // We aren't being strict about token-to-token equivalence of types,
668 // so map down to the canonical type.
669 T1
= Context
.FromCtx
.getCanonicalType(T1
);
670 T2
= Context
.ToCtx
.getCanonicalType(T2
);
673 if (T1
.getQualifiers() != T2
.getQualifiers())
676 Type::TypeClass TC
= T1
->getTypeClass();
678 if (T1
->getTypeClass() != T2
->getTypeClass()) {
679 // Compare function types with prototypes vs. without prototypes as if
680 // both did not have prototypes.
681 if (T1
->getTypeClass() == Type::FunctionProto
&&
682 T2
->getTypeClass() == Type::FunctionNoProto
)
683 TC
= Type::FunctionNoProto
;
684 else if (T1
->getTypeClass() == Type::FunctionNoProto
&&
685 T2
->getTypeClass() == Type::FunctionProto
)
686 TC
= Type::FunctionNoProto
;
693 // FIXME: Deal with Char_S/Char_U.
694 if (cast
<BuiltinType
>(T1
)->getKind() != cast
<BuiltinType
>(T2
)->getKind())
699 if (!IsStructurallyEquivalent(Context
,
700 cast
<ComplexType
>(T1
)->getElementType(),
701 cast
<ComplexType
>(T2
)->getElementType()))
707 if (!IsStructurallyEquivalent(Context
,
708 cast
<AdjustedType
>(T1
)->getOriginalType(),
709 cast
<AdjustedType
>(T2
)->getOriginalType()))
714 if (!IsStructurallyEquivalent(Context
,
715 cast
<PointerType
>(T1
)->getPointeeType(),
716 cast
<PointerType
>(T2
)->getPointeeType()))
720 case Type::BlockPointer
:
721 if (!IsStructurallyEquivalent(Context
,
722 cast
<BlockPointerType
>(T1
)->getPointeeType(),
723 cast
<BlockPointerType
>(T2
)->getPointeeType()))
727 case Type::LValueReference
:
728 case Type::RValueReference
: {
729 const auto *Ref1
= cast
<ReferenceType
>(T1
);
730 const auto *Ref2
= cast
<ReferenceType
>(T2
);
731 if (Ref1
->isSpelledAsLValue() != Ref2
->isSpelledAsLValue())
733 if (Ref1
->isInnerRef() != Ref2
->isInnerRef())
735 if (!IsStructurallyEquivalent(Context
, Ref1
->getPointeeTypeAsWritten(),
736 Ref2
->getPointeeTypeAsWritten()))
741 case Type::MemberPointer
: {
742 const auto *MemPtr1
= cast
<MemberPointerType
>(T1
);
743 const auto *MemPtr2
= cast
<MemberPointerType
>(T2
);
744 if (!IsStructurallyEquivalent(Context
, MemPtr1
->getPointeeType(),
745 MemPtr2
->getPointeeType()))
747 if (!IsStructurallyEquivalent(Context
, QualType(MemPtr1
->getClass(), 0),
748 QualType(MemPtr2
->getClass(), 0)))
753 case Type::ConstantArray
: {
754 const auto *Array1
= cast
<ConstantArrayType
>(T1
);
755 const auto *Array2
= cast
<ConstantArrayType
>(T2
);
756 if (!llvm::APInt::isSameValue(Array1
->getSize(), Array2
->getSize()))
759 if (!IsArrayStructurallyEquivalent(Context
, Array1
, Array2
))
764 case Type::IncompleteArray
:
765 if (!IsArrayStructurallyEquivalent(Context
, cast
<ArrayType
>(T1
),
766 cast
<ArrayType
>(T2
)))
770 case Type::VariableArray
: {
771 const auto *Array1
= cast
<VariableArrayType
>(T1
);
772 const auto *Array2
= cast
<VariableArrayType
>(T2
);
773 if (!IsStructurallyEquivalent(Context
, Array1
->getSizeExpr(),
774 Array2
->getSizeExpr()))
777 if (!IsArrayStructurallyEquivalent(Context
, Array1
, Array2
))
783 case Type::DependentSizedArray
: {
784 const auto *Array1
= cast
<DependentSizedArrayType
>(T1
);
785 const auto *Array2
= cast
<DependentSizedArrayType
>(T2
);
786 if (!IsStructurallyEquivalent(Context
, Array1
->getSizeExpr(),
787 Array2
->getSizeExpr()))
790 if (!IsArrayStructurallyEquivalent(Context
, Array1
, Array2
))
796 case Type::DependentAddressSpace
: {
797 const auto *DepAddressSpace1
= cast
<DependentAddressSpaceType
>(T1
);
798 const auto *DepAddressSpace2
= cast
<DependentAddressSpaceType
>(T2
);
799 if (!IsStructurallyEquivalent(Context
, DepAddressSpace1
->getAddrSpaceExpr(),
800 DepAddressSpace2
->getAddrSpaceExpr()))
802 if (!IsStructurallyEquivalent(Context
, DepAddressSpace1
->getPointeeType(),
803 DepAddressSpace2
->getPointeeType()))
809 case Type::DependentSizedExtVector
: {
810 const auto *Vec1
= cast
<DependentSizedExtVectorType
>(T1
);
811 const auto *Vec2
= cast
<DependentSizedExtVectorType
>(T2
);
812 if (!IsStructurallyEquivalent(Context
, Vec1
->getSizeExpr(),
813 Vec2
->getSizeExpr()))
815 if (!IsStructurallyEquivalent(Context
, Vec1
->getElementType(),
816 Vec2
->getElementType()))
821 case Type::DependentVector
: {
822 const auto *Vec1
= cast
<DependentVectorType
>(T1
);
823 const auto *Vec2
= cast
<DependentVectorType
>(T2
);
824 if (Vec1
->getVectorKind() != Vec2
->getVectorKind())
826 if (!IsStructurallyEquivalent(Context
, Vec1
->getSizeExpr(),
827 Vec2
->getSizeExpr()))
829 if (!IsStructurallyEquivalent(Context
, Vec1
->getElementType(),
830 Vec2
->getElementType()))
836 case Type::ExtVector
: {
837 const auto *Vec1
= cast
<VectorType
>(T1
);
838 const auto *Vec2
= cast
<VectorType
>(T2
);
839 if (!IsStructurallyEquivalent(Context
, Vec1
->getElementType(),
840 Vec2
->getElementType()))
842 if (Vec1
->getNumElements() != Vec2
->getNumElements())
844 if (Vec1
->getVectorKind() != Vec2
->getVectorKind())
849 case Type::DependentSizedMatrix
: {
850 const DependentSizedMatrixType
*Mat1
= cast
<DependentSizedMatrixType
>(T1
);
851 const DependentSizedMatrixType
*Mat2
= cast
<DependentSizedMatrixType
>(T2
);
852 // The element types, row and column expressions must be structurally
854 if (!IsStructurallyEquivalent(Context
, Mat1
->getRowExpr(),
855 Mat2
->getRowExpr()) ||
856 !IsStructurallyEquivalent(Context
, Mat1
->getColumnExpr(),
857 Mat2
->getColumnExpr()) ||
858 !IsStructurallyEquivalent(Context
, Mat1
->getElementType(),
859 Mat2
->getElementType()))
864 case Type::ConstantMatrix
: {
865 const ConstantMatrixType
*Mat1
= cast
<ConstantMatrixType
>(T1
);
866 const ConstantMatrixType
*Mat2
= cast
<ConstantMatrixType
>(T2
);
867 // The element types must be structurally equivalent and the number of rows
868 // and columns must match.
869 if (!IsStructurallyEquivalent(Context
, Mat1
->getElementType(),
870 Mat2
->getElementType()) ||
871 Mat1
->getNumRows() != Mat2
->getNumRows() ||
872 Mat1
->getNumColumns() != Mat2
->getNumColumns())
877 case Type::FunctionProto
: {
878 const auto *Proto1
= cast
<FunctionProtoType
>(T1
);
879 const auto *Proto2
= cast
<FunctionProtoType
>(T2
);
881 if (Proto1
->getNumParams() != Proto2
->getNumParams())
883 for (unsigned I
= 0, N
= Proto1
->getNumParams(); I
!= N
; ++I
) {
884 if (!IsStructurallyEquivalent(Context
, Proto1
->getParamType(I
),
885 Proto2
->getParamType(I
)))
888 if (Proto1
->isVariadic() != Proto2
->isVariadic())
891 if (Proto1
->getMethodQuals() != Proto2
->getMethodQuals())
894 // Check exceptions, this information is lost in canonical type.
895 const auto *OrigProto1
=
896 cast
<FunctionProtoType
>(OrigT1
.getDesugaredType(Context
.FromCtx
));
897 const auto *OrigProto2
=
898 cast
<FunctionProtoType
>(OrigT2
.getDesugaredType(Context
.ToCtx
));
899 if (!IsEquivalentExceptionSpec(Context
, OrigProto1
, OrigProto2
))
902 // Fall through to check the bits common with FunctionNoProtoType.
906 case Type::FunctionNoProto
: {
907 const auto *Function1
= cast
<FunctionType
>(T1
);
908 const auto *Function2
= cast
<FunctionType
>(T2
);
909 if (!IsStructurallyEquivalent(Context
, Function1
->getReturnType(),
910 Function2
->getReturnType()))
912 if (!IsStructurallyEquivalent(Context
, Function1
->getExtInfo(),
913 Function2
->getExtInfo()))
918 case Type::UnresolvedUsing
:
919 if (!IsStructurallyEquivalent(Context
,
920 cast
<UnresolvedUsingType
>(T1
)->getDecl(),
921 cast
<UnresolvedUsingType
>(T2
)->getDecl()))
925 case Type::Attributed
:
926 if (!IsStructurallyEquivalent(Context
,
927 cast
<AttributedType
>(T1
)->getModifiedType(),
928 cast
<AttributedType
>(T2
)->getModifiedType()))
930 if (!IsStructurallyEquivalent(
931 Context
, cast
<AttributedType
>(T1
)->getEquivalentType(),
932 cast
<AttributedType
>(T2
)->getEquivalentType()))
936 case Type::BTFTagAttributed
:
937 if (!IsStructurallyEquivalent(
938 Context
, cast
<BTFTagAttributedType
>(T1
)->getWrappedType(),
939 cast
<BTFTagAttributedType
>(T2
)->getWrappedType()))
944 if (!IsStructurallyEquivalent(Context
, cast
<ParenType
>(T1
)->getInnerType(),
945 cast
<ParenType
>(T2
)->getInnerType()))
949 case Type::MacroQualified
:
950 if (!IsStructurallyEquivalent(
951 Context
, cast
<MacroQualifiedType
>(T1
)->getUnderlyingType(),
952 cast
<MacroQualifiedType
>(T2
)->getUnderlyingType()))
957 if (!IsStructurallyEquivalent(Context
, cast
<UsingType
>(T1
)->getFoundDecl(),
958 cast
<UsingType
>(T2
)->getFoundDecl()))
963 if (!IsStructurallyEquivalent(Context
, cast
<TypedefType
>(T1
)->getDecl(),
964 cast
<TypedefType
>(T2
)->getDecl()))
968 case Type::TypeOfExpr
:
969 if (!IsStructurallyEquivalent(
970 Context
, cast
<TypeOfExprType
>(T1
)->getUnderlyingExpr(),
971 cast
<TypeOfExprType
>(T2
)->getUnderlyingExpr()))
976 if (!IsStructurallyEquivalent(Context
,
977 cast
<TypeOfType
>(T1
)->getUnderlyingType(),
978 cast
<TypeOfType
>(T2
)->getUnderlyingType()))
982 case Type::UnaryTransform
:
983 if (!IsStructurallyEquivalent(
984 Context
, cast
<UnaryTransformType
>(T1
)->getUnderlyingType(),
985 cast
<UnaryTransformType
>(T2
)->getUnderlyingType()))
990 if (!IsStructurallyEquivalent(Context
,
991 cast
<DecltypeType
>(T1
)->getUnderlyingExpr(),
992 cast
<DecltypeType
>(T2
)->getUnderlyingExpr()))
997 auto *Auto1
= cast
<AutoType
>(T1
);
998 auto *Auto2
= cast
<AutoType
>(T2
);
999 if (!IsStructurallyEquivalent(Context
, Auto1
->getDeducedType(),
1000 Auto2
->getDeducedType()))
1002 if (Auto1
->isConstrained() != Auto2
->isConstrained())
1004 if (Auto1
->isConstrained()) {
1005 if (Auto1
->getTypeConstraintConcept() !=
1006 Auto2
->getTypeConstraintConcept())
1008 ArrayRef
<TemplateArgument
> Auto1Args
=
1009 Auto1
->getTypeConstraintArguments();
1010 ArrayRef
<TemplateArgument
> Auto2Args
=
1011 Auto2
->getTypeConstraintArguments();
1012 if (Auto1Args
.size() != Auto2Args
.size())
1014 for (unsigned I
= 0, N
= Auto1Args
.size(); I
!= N
; ++I
) {
1015 if (!IsStructurallyEquivalent(Context
, Auto1Args
[I
], Auto2Args
[I
]))
1022 case Type::DeducedTemplateSpecialization
: {
1023 const auto *DT1
= cast
<DeducedTemplateSpecializationType
>(T1
);
1024 const auto *DT2
= cast
<DeducedTemplateSpecializationType
>(T2
);
1025 if (!IsStructurallyEquivalent(Context
, DT1
->getTemplateName(),
1026 DT2
->getTemplateName()))
1028 if (!IsStructurallyEquivalent(Context
, DT1
->getDeducedType(),
1029 DT2
->getDeducedType()))
1036 if (!IsStructurallyEquivalent(Context
, cast
<TagType
>(T1
)->getDecl(),
1037 cast
<TagType
>(T2
)->getDecl()))
1041 case Type::TemplateTypeParm
: {
1042 const auto *Parm1
= cast
<TemplateTypeParmType
>(T1
);
1043 const auto *Parm2
= cast
<TemplateTypeParmType
>(T2
);
1044 if (Parm1
->getDepth() != Parm2
->getDepth())
1046 if (Parm1
->getIndex() != Parm2
->getIndex())
1048 if (Parm1
->isParameterPack() != Parm2
->isParameterPack())
1051 // Names of template type parameters are never significant.
1055 case Type::SubstTemplateTypeParm
: {
1056 const auto *Subst1
= cast
<SubstTemplateTypeParmType
>(T1
);
1057 const auto *Subst2
= cast
<SubstTemplateTypeParmType
>(T2
);
1058 if (!IsStructurallyEquivalent(Context
,
1059 QualType(Subst1
->getReplacedParameter(), 0),
1060 QualType(Subst2
->getReplacedParameter(), 0)))
1062 if (!IsStructurallyEquivalent(Context
, Subst1
->getReplacementType(),
1063 Subst2
->getReplacementType()))
1065 if (Subst1
->getPackIndex() != Subst2
->getPackIndex())
1070 case Type::SubstTemplateTypeParmPack
: {
1071 const auto *Subst1
= cast
<SubstTemplateTypeParmPackType
>(T1
);
1072 const auto *Subst2
= cast
<SubstTemplateTypeParmPackType
>(T2
);
1073 if (!IsStructurallyEquivalent(Context
,
1074 QualType(Subst1
->getReplacedParameter(), 0),
1075 QualType(Subst2
->getReplacedParameter(), 0)))
1077 if (!IsStructurallyEquivalent(Context
, Subst1
->getArgumentPack(),
1078 Subst2
->getArgumentPack()))
1083 case Type::TemplateSpecialization
: {
1084 const auto *Spec1
= cast
<TemplateSpecializationType
>(T1
);
1085 const auto *Spec2
= cast
<TemplateSpecializationType
>(T2
);
1086 if (!IsStructurallyEquivalent(Context
, Spec1
->getTemplateName(),
1087 Spec2
->getTemplateName()))
1089 if (Spec1
->getNumArgs() != Spec2
->getNumArgs())
1091 for (unsigned I
= 0, N
= Spec1
->getNumArgs(); I
!= N
; ++I
) {
1092 if (!IsStructurallyEquivalent(Context
, Spec1
->getArg(I
),
1099 case Type::Elaborated
: {
1100 const auto *Elab1
= cast
<ElaboratedType
>(T1
);
1101 const auto *Elab2
= cast
<ElaboratedType
>(T2
);
1102 // CHECKME: what if a keyword is ETK_None or ETK_typename ?
1103 if (Elab1
->getKeyword() != Elab2
->getKeyword())
1105 if (!IsStructurallyEquivalent(Context
, Elab1
->getQualifier(),
1106 Elab2
->getQualifier()))
1108 if (!IsStructurallyEquivalent(Context
, Elab1
->getNamedType(),
1109 Elab2
->getNamedType()))
1114 case Type::InjectedClassName
: {
1115 const auto *Inj1
= cast
<InjectedClassNameType
>(T1
);
1116 const auto *Inj2
= cast
<InjectedClassNameType
>(T2
);
1117 if (!IsStructurallyEquivalent(Context
,
1118 Inj1
->getInjectedSpecializationType(),
1119 Inj2
->getInjectedSpecializationType()))
1124 case Type::DependentName
: {
1125 const auto *Typename1
= cast
<DependentNameType
>(T1
);
1126 const auto *Typename2
= cast
<DependentNameType
>(T2
);
1127 if (!IsStructurallyEquivalent(Context
, Typename1
->getQualifier(),
1128 Typename2
->getQualifier()))
1130 if (!IsStructurallyEquivalent(Typename1
->getIdentifier(),
1131 Typename2
->getIdentifier()))
1137 case Type::DependentTemplateSpecialization
: {
1138 const auto *Spec1
= cast
<DependentTemplateSpecializationType
>(T1
);
1139 const auto *Spec2
= cast
<DependentTemplateSpecializationType
>(T2
);
1140 if (!IsStructurallyEquivalent(Context
, Spec1
->getQualifier(),
1141 Spec2
->getQualifier()))
1143 if (!IsStructurallyEquivalent(Spec1
->getIdentifier(),
1144 Spec2
->getIdentifier()))
1146 if (Spec1
->getNumArgs() != Spec2
->getNumArgs())
1148 for (unsigned I
= 0, N
= Spec1
->getNumArgs(); I
!= N
; ++I
) {
1149 if (!IsStructurallyEquivalent(Context
, Spec1
->getArg(I
),
1156 case Type::PackExpansion
:
1157 if (!IsStructurallyEquivalent(Context
,
1158 cast
<PackExpansionType
>(T1
)->getPattern(),
1159 cast
<PackExpansionType
>(T2
)->getPattern()))
1163 case Type::ObjCInterface
: {
1164 const auto *Iface1
= cast
<ObjCInterfaceType
>(T1
);
1165 const auto *Iface2
= cast
<ObjCInterfaceType
>(T2
);
1166 if (!IsStructurallyEquivalent(Context
, Iface1
->getDecl(),
1172 case Type::ObjCTypeParam
: {
1173 const auto *Obj1
= cast
<ObjCTypeParamType
>(T1
);
1174 const auto *Obj2
= cast
<ObjCTypeParamType
>(T2
);
1175 if (!IsStructurallyEquivalent(Context
, Obj1
->getDecl(), Obj2
->getDecl()))
1178 if (Obj1
->getNumProtocols() != Obj2
->getNumProtocols())
1180 for (unsigned I
= 0, N
= Obj1
->getNumProtocols(); I
!= N
; ++I
) {
1181 if (!IsStructurallyEquivalent(Context
, Obj1
->getProtocol(I
),
1182 Obj2
->getProtocol(I
)))
1188 case Type::ObjCObject
: {
1189 const auto *Obj1
= cast
<ObjCObjectType
>(T1
);
1190 const auto *Obj2
= cast
<ObjCObjectType
>(T2
);
1191 if (!IsStructurallyEquivalent(Context
, Obj1
->getBaseType(),
1192 Obj2
->getBaseType()))
1194 if (Obj1
->getNumProtocols() != Obj2
->getNumProtocols())
1196 for (unsigned I
= 0, N
= Obj1
->getNumProtocols(); I
!= N
; ++I
) {
1197 if (!IsStructurallyEquivalent(Context
, Obj1
->getProtocol(I
),
1198 Obj2
->getProtocol(I
)))
1204 case Type::ObjCObjectPointer
: {
1205 const auto *Ptr1
= cast
<ObjCObjectPointerType
>(T1
);
1206 const auto *Ptr2
= cast
<ObjCObjectPointerType
>(T2
);
1207 if (!IsStructurallyEquivalent(Context
, Ptr1
->getPointeeType(),
1208 Ptr2
->getPointeeType()))
1214 if (!IsStructurallyEquivalent(Context
, cast
<AtomicType
>(T1
)->getValueType(),
1215 cast
<AtomicType
>(T2
)->getValueType()))
1220 if (!IsStructurallyEquivalent(Context
, cast
<PipeType
>(T1
)->getElementType(),
1221 cast
<PipeType
>(T2
)->getElementType()))
1224 case Type::BitInt
: {
1225 const auto *Int1
= cast
<BitIntType
>(T1
);
1226 const auto *Int2
= cast
<BitIntType
>(T2
);
1228 if (Int1
->isUnsigned() != Int2
->isUnsigned() ||
1229 Int1
->getNumBits() != Int2
->getNumBits())
1233 case Type::DependentBitInt
: {
1234 const auto *Int1
= cast
<DependentBitIntType
>(T1
);
1235 const auto *Int2
= cast
<DependentBitIntType
>(T2
);
1237 if (Int1
->isUnsigned() != Int2
->isUnsigned() ||
1238 !IsStructurallyEquivalent(Context
, Int1
->getNumBitsExpr(),
1239 Int2
->getNumBitsExpr()))
1248 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1249 FieldDecl
*Field1
, FieldDecl
*Field2
,
1250 QualType Owner2Type
) {
1251 const auto *Owner2
= cast
<Decl
>(Field2
->getDeclContext());
1253 // For anonymous structs/unions, match up the anonymous struct/union type
1254 // declarations directly, so that we don't go off searching for anonymous
1256 if (Field1
->isAnonymousStructOrUnion() &&
1257 Field2
->isAnonymousStructOrUnion()) {
1258 RecordDecl
*D1
= Field1
->getType()->castAs
<RecordType
>()->getDecl();
1259 RecordDecl
*D2
= Field2
->getType()->castAs
<RecordType
>()->getDecl();
1260 return IsStructurallyEquivalent(Context
, D1
, D2
);
1263 // Check for equivalent field names.
1264 IdentifierInfo
*Name1
= Field1
->getIdentifier();
1265 IdentifierInfo
*Name2
= Field2
->getIdentifier();
1266 if (!::IsStructurallyEquivalent(Name1
, Name2
)) {
1267 if (Context
.Complain
) {
1269 Owner2
->getLocation(),
1270 Context
.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent
))
1272 Context
.Diag2(Field2
->getLocation(), diag::note_odr_field_name
)
1273 << Field2
->getDeclName();
1274 Context
.Diag1(Field1
->getLocation(), diag::note_odr_field_name
)
1275 << Field1
->getDeclName();
1280 if (!IsStructurallyEquivalent(Context
, Field1
->getType(),
1281 Field2
->getType())) {
1282 if (Context
.Complain
) {
1284 Owner2
->getLocation(),
1285 Context
.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent
))
1287 Context
.Diag2(Field2
->getLocation(), diag::note_odr_field
)
1288 << Field2
->getDeclName() << Field2
->getType();
1289 Context
.Diag1(Field1
->getLocation(), diag::note_odr_field
)
1290 << Field1
->getDeclName() << Field1
->getType();
1295 if (Field1
->isBitField())
1296 return IsStructurallyEquivalent(Context
, Field1
->getBitWidth(),
1297 Field2
->getBitWidth());
1302 /// Determine structural equivalence of two fields.
1303 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1304 FieldDecl
*Field1
, FieldDecl
*Field2
) {
1305 const auto *Owner2
= cast
<RecordDecl
>(Field2
->getDeclContext());
1306 return IsStructurallyEquivalent(Context
, Field1
, Field2
,
1307 Context
.ToCtx
.getTypeDeclType(Owner2
));
1310 /// Determine structural equivalence of two methods.
1311 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1312 CXXMethodDecl
*Method1
,
1313 CXXMethodDecl
*Method2
) {
1314 bool PropertiesEqual
=
1315 Method1
->getDeclKind() == Method2
->getDeclKind() &&
1316 Method1
->getRefQualifier() == Method2
->getRefQualifier() &&
1317 Method1
->getAccess() == Method2
->getAccess() &&
1318 Method1
->getOverloadedOperator() == Method2
->getOverloadedOperator() &&
1319 Method1
->isStatic() == Method2
->isStatic() &&
1320 Method1
->isConst() == Method2
->isConst() &&
1321 Method1
->isVolatile() == Method2
->isVolatile() &&
1322 Method1
->isVirtual() == Method2
->isVirtual() &&
1323 Method1
->isPure() == Method2
->isPure() &&
1324 Method1
->isDefaulted() == Method2
->isDefaulted() &&
1325 Method1
->isDeleted() == Method2
->isDeleted();
1326 if (!PropertiesEqual
)
1328 // FIXME: Check for 'final'.
1330 if (auto *Constructor1
= dyn_cast
<CXXConstructorDecl
>(Method1
)) {
1331 auto *Constructor2
= cast
<CXXConstructorDecl
>(Method2
);
1332 if (!Constructor1
->getExplicitSpecifier().isEquivalent(
1333 Constructor2
->getExplicitSpecifier()))
1337 if (auto *Conversion1
= dyn_cast
<CXXConversionDecl
>(Method1
)) {
1338 auto *Conversion2
= cast
<CXXConversionDecl
>(Method2
);
1339 if (!Conversion1
->getExplicitSpecifier().isEquivalent(
1340 Conversion2
->getExplicitSpecifier()))
1342 if (!IsStructurallyEquivalent(Context
, Conversion1
->getConversionType(),
1343 Conversion2
->getConversionType()))
1347 const IdentifierInfo
*Name1
= Method1
->getIdentifier();
1348 const IdentifierInfo
*Name2
= Method2
->getIdentifier();
1349 if (!::IsStructurallyEquivalent(Name1
, Name2
)) {
1351 // TODO: Names do not match, add warning like at check for FieldDecl.
1354 // Check the prototypes.
1355 if (!::IsStructurallyEquivalent(Context
,
1356 Method1
->getType(), Method2
->getType()))
1362 /// Determine structural equivalence of two lambda classes.
1364 IsStructurallyEquivalentLambdas(StructuralEquivalenceContext
&Context
,
1365 CXXRecordDecl
*D1
, CXXRecordDecl
*D2
) {
1366 assert(D1
->isLambda() && D2
->isLambda() &&
1367 "Must be called on lambda classes");
1368 if (!IsStructurallyEquivalent(Context
, D1
->getLambdaCallOperator(),
1369 D2
->getLambdaCallOperator()))
1375 /// Determine if context of a class is equivalent.
1376 static bool IsRecordContextStructurallyEquivalent(RecordDecl
*D1
,
1378 // The context should be completely equal, including anonymous and inline
1380 // We compare objects as part of full translation units, not subtrees of
1381 // translation units.
1382 DeclContext
*DC1
= D1
->getDeclContext()->getNonTransparentContext();
1383 DeclContext
*DC2
= D2
->getDeclContext()->getNonTransparentContext();
1385 // Special case: We allow a struct defined in a function to be equivalent
1386 // with a similar struct defined outside of a function.
1387 if ((DC1
->isFunctionOrMethod() && DC2
->isTranslationUnit()) ||
1388 (DC2
->isFunctionOrMethod() && DC1
->isTranslationUnit()))
1391 if (DC1
->getDeclKind() != DC2
->getDeclKind())
1393 if (DC1
->isTranslationUnit())
1395 if (DC1
->isInlineNamespace() != DC2
->isInlineNamespace())
1397 if (const auto *ND1
= dyn_cast
<NamedDecl
>(DC1
)) {
1398 const auto *ND2
= cast
<NamedDecl
>(DC2
);
1399 if (!DC1
->isInlineNamespace() &&
1400 !IsStructurallyEquivalent(ND1
->getIdentifier(), ND2
->getIdentifier()))
1404 DC1
= DC1
->getParent()->getNonTransparentContext();
1405 DC2
= DC2
->getParent()->getNonTransparentContext();
1411 /// Determine structural equivalence of two records.
1412 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1413 RecordDecl
*D1
, RecordDecl
*D2
) {
1415 // Check for equivalent structure names.
1416 IdentifierInfo
*Name1
= D1
->getIdentifier();
1417 if (!Name1
&& D1
->getTypedefNameForAnonDecl())
1418 Name1
= D1
->getTypedefNameForAnonDecl()->getIdentifier();
1419 IdentifierInfo
*Name2
= D2
->getIdentifier();
1420 if (!Name2
&& D2
->getTypedefNameForAnonDecl())
1421 Name2
= D2
->getTypedefNameForAnonDecl()->getIdentifier();
1422 if (!IsStructurallyEquivalent(Name1
, Name2
))
1425 if (D1
->isUnion() != D2
->isUnion()) {
1426 if (Context
.Complain
) {
1427 Context
.Diag2(D2
->getLocation(), Context
.getApplicableDiagnostic(
1428 diag::err_odr_tag_type_inconsistent
))
1429 << Context
.ToCtx
.getTypeDeclType(D2
);
1430 Context
.Diag1(D1
->getLocation(), diag::note_odr_tag_kind_here
)
1431 << D1
->getDeclName() << (unsigned)D1
->getTagKind();
1436 if (!D1
->getDeclName() && !D2
->getDeclName()) {
1437 // If both anonymous structs/unions are in a record context, make sure
1438 // they occur in the same location in the context records.
1439 if (Optional
<unsigned> Index1
=
1440 StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(D1
)) {
1441 if (Optional
<unsigned> Index2
=
1442 StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(
1444 if (*Index1
!= *Index2
)
1450 // If the records occur in different context (namespace), these should be
1451 // different. This is specially important if the definition of one or both
1452 // records is missing.
1453 if (!IsRecordContextStructurallyEquivalent(D1
, D2
))
1456 // If both declarations are class template specializations, we know
1457 // the ODR applies, so check the template and template arguments.
1458 const auto *Spec1
= dyn_cast
<ClassTemplateSpecializationDecl
>(D1
);
1459 const auto *Spec2
= dyn_cast
<ClassTemplateSpecializationDecl
>(D2
);
1460 if (Spec1
&& Spec2
) {
1461 // Check that the specialized templates are the same.
1462 if (!IsStructurallyEquivalent(Context
, Spec1
->getSpecializedTemplate(),
1463 Spec2
->getSpecializedTemplate()))
1466 // Check that the template arguments are the same.
1467 if (Spec1
->getTemplateArgs().size() != Spec2
->getTemplateArgs().size())
1470 for (unsigned I
= 0, N
= Spec1
->getTemplateArgs().size(); I
!= N
; ++I
)
1471 if (!IsStructurallyEquivalent(Context
, Spec1
->getTemplateArgs().get(I
),
1472 Spec2
->getTemplateArgs().get(I
)))
1475 // If one is a class template specialization and the other is not, these
1476 // structures are different.
1477 else if (Spec1
|| Spec2
)
1480 // Compare the definitions of these two records. If either or both are
1481 // incomplete (i.e. it is a forward decl), we assume that they are
1483 D1
= D1
->getDefinition();
1484 D2
= D2
->getDefinition();
1488 // If any of the records has external storage and we do a minimal check (or
1489 // AST import) we assume they are equivalent. (If we didn't have this
1490 // assumption then `RecordDecl::LoadFieldsFromExternalStorage` could trigger
1491 // another AST import which in turn would call the structural equivalency
1492 // check again and finally we'd have an improper result.)
1493 if (Context
.EqKind
== StructuralEquivalenceKind::Minimal
)
1494 if (D1
->hasExternalLexicalStorage() || D2
->hasExternalLexicalStorage())
1497 // If one definition is currently being defined, we do not compare for
1498 // equality and we assume that the decls are equal.
1499 if (D1
->isBeingDefined() || D2
->isBeingDefined())
1502 if (auto *D1CXX
= dyn_cast
<CXXRecordDecl
>(D1
)) {
1503 if (auto *D2CXX
= dyn_cast
<CXXRecordDecl
>(D2
)) {
1504 if (D1CXX
->hasExternalLexicalStorage() &&
1505 !D1CXX
->isCompleteDefinition()) {
1506 D1CXX
->getASTContext().getExternalSource()->CompleteType(D1CXX
);
1509 if (D1CXX
->isLambda() != D2CXX
->isLambda())
1511 if (D1CXX
->isLambda()) {
1512 if (!IsStructurallyEquivalentLambdas(Context
, D1CXX
, D2CXX
))
1516 if (D1CXX
->getNumBases() != D2CXX
->getNumBases()) {
1517 if (Context
.Complain
) {
1518 Context
.Diag2(D2
->getLocation(),
1519 Context
.getApplicableDiagnostic(
1520 diag::err_odr_tag_type_inconsistent
))
1521 << Context
.ToCtx
.getTypeDeclType(D2
);
1522 Context
.Diag2(D2
->getLocation(), diag::note_odr_number_of_bases
)
1523 << D2CXX
->getNumBases();
1524 Context
.Diag1(D1
->getLocation(), diag::note_odr_number_of_bases
)
1525 << D1CXX
->getNumBases();
1530 // Check the base classes.
1531 for (CXXRecordDecl::base_class_iterator Base1
= D1CXX
->bases_begin(),
1532 BaseEnd1
= D1CXX
->bases_end(),
1533 Base2
= D2CXX
->bases_begin();
1534 Base1
!= BaseEnd1
; ++Base1
, ++Base2
) {
1535 if (!IsStructurallyEquivalent(Context
, Base1
->getType(),
1536 Base2
->getType())) {
1537 if (Context
.Complain
) {
1538 Context
.Diag2(D2
->getLocation(),
1539 Context
.getApplicableDiagnostic(
1540 diag::err_odr_tag_type_inconsistent
))
1541 << Context
.ToCtx
.getTypeDeclType(D2
);
1542 Context
.Diag2(Base2
->getBeginLoc(), diag::note_odr_base
)
1543 << Base2
->getType() << Base2
->getSourceRange();
1544 Context
.Diag1(Base1
->getBeginLoc(), diag::note_odr_base
)
1545 << Base1
->getType() << Base1
->getSourceRange();
1550 // Check virtual vs. non-virtual inheritance mismatch.
1551 if (Base1
->isVirtual() != Base2
->isVirtual()) {
1552 if (Context
.Complain
) {
1553 Context
.Diag2(D2
->getLocation(),
1554 Context
.getApplicableDiagnostic(
1555 diag::err_odr_tag_type_inconsistent
))
1556 << Context
.ToCtx
.getTypeDeclType(D2
);
1557 Context
.Diag2(Base2
->getBeginLoc(), diag::note_odr_virtual_base
)
1558 << Base2
->isVirtual() << Base2
->getSourceRange();
1559 Context
.Diag1(Base1
->getBeginLoc(), diag::note_odr_base
)
1560 << Base1
->isVirtual() << Base1
->getSourceRange();
1566 // Check the friends for consistency.
1567 CXXRecordDecl::friend_iterator Friend2
= D2CXX
->friend_begin(),
1568 Friend2End
= D2CXX
->friend_end();
1569 for (CXXRecordDecl::friend_iterator Friend1
= D1CXX
->friend_begin(),
1570 Friend1End
= D1CXX
->friend_end();
1571 Friend1
!= Friend1End
; ++Friend1
, ++Friend2
) {
1572 if (Friend2
== Friend2End
) {
1573 if (Context
.Complain
) {
1574 Context
.Diag2(D2
->getLocation(),
1575 Context
.getApplicableDiagnostic(
1576 diag::err_odr_tag_type_inconsistent
))
1577 << Context
.ToCtx
.getTypeDeclType(D2CXX
);
1578 Context
.Diag1((*Friend1
)->getFriendLoc(), diag::note_odr_friend
);
1579 Context
.Diag2(D2
->getLocation(), diag::note_odr_missing_friend
);
1584 if (!IsStructurallyEquivalent(Context
, *Friend1
, *Friend2
)) {
1585 if (Context
.Complain
) {
1586 Context
.Diag2(D2
->getLocation(),
1587 Context
.getApplicableDiagnostic(
1588 diag::err_odr_tag_type_inconsistent
))
1589 << Context
.ToCtx
.getTypeDeclType(D2CXX
);
1590 Context
.Diag1((*Friend1
)->getFriendLoc(), diag::note_odr_friend
);
1591 Context
.Diag2((*Friend2
)->getFriendLoc(), diag::note_odr_friend
);
1597 if (Friend2
!= Friend2End
) {
1598 if (Context
.Complain
) {
1599 Context
.Diag2(D2
->getLocation(),
1600 Context
.getApplicableDiagnostic(
1601 diag::err_odr_tag_type_inconsistent
))
1602 << Context
.ToCtx
.getTypeDeclType(D2
);
1603 Context
.Diag2((*Friend2
)->getFriendLoc(), diag::note_odr_friend
);
1604 Context
.Diag1(D1
->getLocation(), diag::note_odr_missing_friend
);
1608 } else if (D1CXX
->getNumBases() > 0) {
1609 if (Context
.Complain
) {
1610 Context
.Diag2(D2
->getLocation(),
1611 Context
.getApplicableDiagnostic(
1612 diag::err_odr_tag_type_inconsistent
))
1613 << Context
.ToCtx
.getTypeDeclType(D2
);
1614 const CXXBaseSpecifier
*Base1
= D1CXX
->bases_begin();
1615 Context
.Diag1(Base1
->getBeginLoc(), diag::note_odr_base
)
1616 << Base1
->getType() << Base1
->getSourceRange();
1617 Context
.Diag2(D2
->getLocation(), diag::note_odr_missing_base
);
1623 // Check the fields for consistency.
1624 QualType D2Type
= Context
.ToCtx
.getTypeDeclType(D2
);
1625 RecordDecl::field_iterator Field2
= D2
->field_begin(),
1626 Field2End
= D2
->field_end();
1627 for (RecordDecl::field_iterator Field1
= D1
->field_begin(),
1628 Field1End
= D1
->field_end();
1629 Field1
!= Field1End
; ++Field1
, ++Field2
) {
1630 if (Field2
== Field2End
) {
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
.Diag1(Field1
->getLocation(), diag::note_odr_field
)
1637 << Field1
->getDeclName() << Field1
->getType();
1638 Context
.Diag2(D2
->getLocation(), diag::note_odr_missing_field
);
1643 if (!IsStructurallyEquivalent(Context
, *Field1
, *Field2
, D2Type
))
1647 if (Field2
!= Field2End
) {
1648 if (Context
.Complain
) {
1649 Context
.Diag2(D2
->getLocation(), Context
.getApplicableDiagnostic(
1650 diag::err_odr_tag_type_inconsistent
))
1651 << Context
.ToCtx
.getTypeDeclType(D2
);
1652 Context
.Diag2(Field2
->getLocation(), diag::note_odr_field
)
1653 << Field2
->getDeclName() << Field2
->getType();
1654 Context
.Diag1(D1
->getLocation(), diag::note_odr_missing_field
);
1662 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1663 EnumConstantDecl
*D1
,
1664 EnumConstantDecl
*D2
) {
1665 const llvm::APSInt
&FromVal
= D1
->getInitVal();
1666 const llvm::APSInt
&ToVal
= D2
->getInitVal();
1667 if (FromVal
.isSigned() != ToVal
.isSigned())
1669 if (FromVal
.getBitWidth() != ToVal
.getBitWidth())
1671 if (FromVal
!= ToVal
)
1674 if (!IsStructurallyEquivalent(D1
->getIdentifier(), D2
->getIdentifier()))
1677 // Init expressions are the most expensive check, so do them last.
1678 return IsStructurallyEquivalent(Context
, D1
->getInitExpr(),
1682 /// Determine structural equivalence of two enums.
1683 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1684 EnumDecl
*D1
, EnumDecl
*D2
) {
1686 // Check for equivalent enum names.
1687 IdentifierInfo
*Name1
= D1
->getIdentifier();
1688 if (!Name1
&& D1
->getTypedefNameForAnonDecl())
1689 Name1
= D1
->getTypedefNameForAnonDecl()->getIdentifier();
1690 IdentifierInfo
*Name2
= D2
->getIdentifier();
1691 if (!Name2
&& D2
->getTypedefNameForAnonDecl())
1692 Name2
= D2
->getTypedefNameForAnonDecl()->getIdentifier();
1693 if (!IsStructurallyEquivalent(Name1
, Name2
))
1696 // Compare the definitions of these two enums. If either or both are
1697 // incomplete (i.e. forward declared), we assume that they are equivalent.
1698 D1
= D1
->getDefinition();
1699 D2
= D2
->getDefinition();
1703 EnumDecl::enumerator_iterator EC2
= D2
->enumerator_begin(),
1704 EC2End
= D2
->enumerator_end();
1705 for (EnumDecl::enumerator_iterator EC1
= D1
->enumerator_begin(),
1706 EC1End
= D1
->enumerator_end();
1707 EC1
!= EC1End
; ++EC1
, ++EC2
) {
1708 if (EC2
== EC2End
) {
1709 if (Context
.Complain
) {
1710 Context
.Diag2(D2
->getLocation(),
1711 Context
.getApplicableDiagnostic(
1712 diag::err_odr_tag_type_inconsistent
))
1713 << Context
.ToCtx
.getTypeDeclType(D2
);
1714 Context
.Diag1(EC1
->getLocation(), diag::note_odr_enumerator
)
1715 << EC1
->getDeclName() << toString(EC1
->getInitVal(), 10);
1716 Context
.Diag2(D2
->getLocation(), diag::note_odr_missing_enumerator
);
1721 llvm::APSInt Val1
= EC1
->getInitVal();
1722 llvm::APSInt Val2
= EC2
->getInitVal();
1723 if (!llvm::APSInt::isSameValue(Val1
, Val2
) ||
1724 !IsStructurallyEquivalent(EC1
->getIdentifier(), EC2
->getIdentifier())) {
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
.Diag2(EC2
->getLocation(), diag::note_odr_enumerator
)
1731 << EC2
->getDeclName() << toString(EC2
->getInitVal(), 10);
1732 Context
.Diag1(EC1
->getLocation(), diag::note_odr_enumerator
)
1733 << EC1
->getDeclName() << toString(EC1
->getInitVal(), 10);
1739 if (EC2
!= EC2End
) {
1740 if (Context
.Complain
) {
1741 Context
.Diag2(D2
->getLocation(), Context
.getApplicableDiagnostic(
1742 diag::err_odr_tag_type_inconsistent
))
1743 << Context
.ToCtx
.getTypeDeclType(D2
);
1744 Context
.Diag2(EC2
->getLocation(), diag::note_odr_enumerator
)
1745 << EC2
->getDeclName() << toString(EC2
->getInitVal(), 10);
1746 Context
.Diag1(D1
->getLocation(), diag::note_odr_missing_enumerator
);
1754 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1755 TemplateParameterList
*Params1
,
1756 TemplateParameterList
*Params2
) {
1757 if (Params1
->size() != Params2
->size()) {
1758 if (Context
.Complain
) {
1759 Context
.Diag2(Params2
->getTemplateLoc(),
1760 Context
.getApplicableDiagnostic(
1761 diag::err_odr_different_num_template_parameters
))
1762 << Params1
->size() << Params2
->size();
1763 Context
.Diag1(Params1
->getTemplateLoc(),
1764 diag::note_odr_template_parameter_list
);
1769 for (unsigned I
= 0, N
= Params1
->size(); I
!= N
; ++I
) {
1770 if (Params1
->getParam(I
)->getKind() != Params2
->getParam(I
)->getKind()) {
1771 if (Context
.Complain
) {
1772 Context
.Diag2(Params2
->getParam(I
)->getLocation(),
1773 Context
.getApplicableDiagnostic(
1774 diag::err_odr_different_template_parameter_kind
));
1775 Context
.Diag1(Params1
->getParam(I
)->getLocation(),
1776 diag::note_odr_template_parameter_here
);
1781 if (!IsStructurallyEquivalent(Context
, Params1
->getParam(I
),
1782 Params2
->getParam(I
)))
1789 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1790 TemplateTypeParmDecl
*D1
,
1791 TemplateTypeParmDecl
*D2
) {
1792 if (D1
->isParameterPack() != D2
->isParameterPack()) {
1793 if (Context
.Complain
) {
1794 Context
.Diag2(D2
->getLocation(),
1795 Context
.getApplicableDiagnostic(
1796 diag::err_odr_parameter_pack_non_pack
))
1797 << D2
->isParameterPack();
1798 Context
.Diag1(D1
->getLocation(), diag::note_odr_parameter_pack_non_pack
)
1799 << D1
->isParameterPack();
1807 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1808 NonTypeTemplateParmDecl
*D1
,
1809 NonTypeTemplateParmDecl
*D2
) {
1810 if (D1
->isParameterPack() != D2
->isParameterPack()) {
1811 if (Context
.Complain
) {
1812 Context
.Diag2(D2
->getLocation(),
1813 Context
.getApplicableDiagnostic(
1814 diag::err_odr_parameter_pack_non_pack
))
1815 << D2
->isParameterPack();
1816 Context
.Diag1(D1
->getLocation(), diag::note_odr_parameter_pack_non_pack
)
1817 << D1
->isParameterPack();
1823 if (!IsStructurallyEquivalent(Context
, D1
->getType(), D2
->getType())) {
1824 if (Context
.Complain
) {
1825 Context
.Diag2(D2
->getLocation(),
1826 Context
.getApplicableDiagnostic(
1827 diag::err_odr_non_type_parameter_type_inconsistent
))
1828 << D2
->getType() << D1
->getType();
1829 Context
.Diag1(D1
->getLocation(), diag::note_odr_value_here
)
1838 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1839 TemplateTemplateParmDecl
*D1
,
1840 TemplateTemplateParmDecl
*D2
) {
1841 if (D1
->isParameterPack() != D2
->isParameterPack()) {
1842 if (Context
.Complain
) {
1843 Context
.Diag2(D2
->getLocation(),
1844 Context
.getApplicableDiagnostic(
1845 diag::err_odr_parameter_pack_non_pack
))
1846 << D2
->isParameterPack();
1847 Context
.Diag1(D1
->getLocation(), diag::note_odr_parameter_pack_non_pack
)
1848 << D1
->isParameterPack();
1853 // Check template parameter lists.
1854 return IsStructurallyEquivalent(Context
, D1
->getTemplateParameters(),
1855 D2
->getTemplateParameters());
1858 static bool IsTemplateDeclCommonStructurallyEquivalent(
1859 StructuralEquivalenceContext
&Ctx
, TemplateDecl
*D1
, TemplateDecl
*D2
) {
1860 if (!IsStructurallyEquivalent(D1
->getIdentifier(), D2
->getIdentifier()))
1862 if (!D1
->getIdentifier()) // Special name
1863 if (D1
->getNameAsString() != D2
->getNameAsString())
1865 return IsStructurallyEquivalent(Ctx
, D1
->getTemplateParameters(),
1866 D2
->getTemplateParameters());
1869 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1870 ClassTemplateDecl
*D1
,
1871 ClassTemplateDecl
*D2
) {
1872 // Check template parameters.
1873 if (!IsTemplateDeclCommonStructurallyEquivalent(Context
, D1
, D2
))
1876 // Check the templated declaration.
1877 return IsStructurallyEquivalent(Context
, D1
->getTemplatedDecl(),
1878 D2
->getTemplatedDecl());
1881 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1882 FunctionTemplateDecl
*D1
,
1883 FunctionTemplateDecl
*D2
) {
1884 // Check template parameters.
1885 if (!IsTemplateDeclCommonStructurallyEquivalent(Context
, D1
, D2
))
1888 // Check the templated declaration.
1889 return IsStructurallyEquivalent(Context
, D1
->getTemplatedDecl()->getType(),
1890 D2
->getTemplatedDecl()->getType());
1893 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1896 // Check template parameters.
1897 if (!IsTemplateDeclCommonStructurallyEquivalent(Context
, D1
, D2
))
1900 // Check the constraint expression.
1901 return IsStructurallyEquivalent(Context
, D1
->getConstraintExpr(),
1902 D2
->getConstraintExpr());
1905 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1906 FriendDecl
*D1
, FriendDecl
*D2
) {
1907 if ((D1
->getFriendType() && D2
->getFriendDecl()) ||
1908 (D1
->getFriendDecl() && D2
->getFriendType())) {
1911 if (D1
->getFriendType() && D2
->getFriendType())
1912 return IsStructurallyEquivalent(Context
,
1913 D1
->getFriendType()->getType(),
1914 D2
->getFriendType()->getType());
1915 if (D1
->getFriendDecl() && D2
->getFriendDecl())
1916 return IsStructurallyEquivalent(Context
, D1
->getFriendDecl(),
1917 D2
->getFriendDecl());
1921 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1922 TypedefNameDecl
*D1
, TypedefNameDecl
*D2
) {
1923 if (!IsStructurallyEquivalent(D1
->getIdentifier(), D2
->getIdentifier()))
1926 return IsStructurallyEquivalent(Context
, D1
->getUnderlyingType(),
1927 D2
->getUnderlyingType());
1930 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1931 FunctionDecl
*D1
, FunctionDecl
*D2
) {
1932 if (!IsStructurallyEquivalent(D1
->getIdentifier(), D2
->getIdentifier()))
1935 if (D1
->isOverloadedOperator()) {
1936 if (!D2
->isOverloadedOperator())
1938 if (D1
->getOverloadedOperator() != D2
->getOverloadedOperator())
1942 // FIXME: Consider checking for function attributes as well.
1943 if (!IsStructurallyEquivalent(Context
, D1
->getType(), D2
->getType()))
1949 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1950 ObjCIvarDecl
*D1
, ObjCIvarDecl
*D2
,
1951 QualType Owner2Type
) {
1952 if (D1
->getAccessControl() != D2
->getAccessControl())
1955 return IsStructurallyEquivalent(Context
, cast
<FieldDecl
>(D1
),
1956 cast
<FieldDecl
>(D2
), Owner2Type
);
1959 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1960 ObjCIvarDecl
*D1
, ObjCIvarDecl
*D2
) {
1961 QualType Owner2Type
=
1962 Context
.ToCtx
.getObjCInterfaceType(D2
->getContainingInterface());
1963 return IsStructurallyEquivalent(Context
, D1
, D2
, Owner2Type
);
1966 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
1967 ObjCMethodDecl
*Method1
,
1968 ObjCMethodDecl
*Method2
) {
1969 bool PropertiesEqual
=
1970 Method1
->isInstanceMethod() == Method2
->isInstanceMethod() &&
1971 Method1
->isVariadic() == Method2
->isVariadic() &&
1972 Method1
->isDirectMethod() == Method2
->isDirectMethod();
1973 if (!PropertiesEqual
)
1976 // Compare selector slot names.
1977 Selector Selector1
= Method1
->getSelector(),
1978 Selector2
= Method2
->getSelector();
1979 unsigned NumArgs
= Selector1
.getNumArgs();
1980 if (NumArgs
!= Selector2
.getNumArgs())
1982 // Compare all selector slots. For selectors with arguments it means all arg
1983 // slots. And if there are no arguments, compare the first-and-only slot.
1984 unsigned SlotsToCheck
= NumArgs
> 0 ? NumArgs
: 1;
1985 for (unsigned I
= 0; I
< SlotsToCheck
; ++I
) {
1986 if (!IsStructurallyEquivalent(Selector1
.getIdentifierInfoForSlot(I
),
1987 Selector2
.getIdentifierInfoForSlot(I
)))
1992 if (!IsStructurallyEquivalent(Context
, Method1
->getReturnType(),
1993 Method2
->getReturnType()))
1996 Method1
->param_size() == Method2
->param_size() &&
1997 "Same number of arguments should be already enforced in Selector checks");
1998 for (ObjCMethodDecl::param_type_iterator
1999 ParamT1
= Method1
->param_type_begin(),
2000 ParamT1End
= Method1
->param_type_end(),
2001 ParamT2
= Method2
->param_type_begin(),
2002 ParamT2End
= Method2
->param_type_end();
2003 (ParamT1
!= ParamT1End
) && (ParamT2
!= ParamT2End
);
2004 ++ParamT1
, ++ParamT2
) {
2005 if (!IsStructurallyEquivalent(Context
, *ParamT1
, *ParamT2
))
2012 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
2013 ObjCCategoryDecl
*D1
,
2014 ObjCCategoryDecl
*D2
) {
2015 if (!IsStructurallyEquivalent(D1
->getIdentifier(), D2
->getIdentifier()))
2018 if (!IsStructurallyEquivalent(D1
->getClassInterface()->getIdentifier(),
2019 D2
->getClassInterface()->getIdentifier()))
2022 // Compare protocols.
2023 ObjCCategoryDecl::protocol_iterator Protocol2
= D2
->protocol_begin(),
2024 Protocol2End
= D2
->protocol_end();
2025 for (ObjCCategoryDecl::protocol_iterator Protocol1
= D1
->protocol_begin(),
2026 Protocol1End
= D1
->protocol_end();
2027 Protocol1
!= Protocol1End
; ++Protocol1
, ++Protocol2
) {
2028 if (Protocol2
== Protocol2End
)
2030 if (!IsStructurallyEquivalent((*Protocol1
)->getIdentifier(),
2031 (*Protocol2
)->getIdentifier()))
2034 if (Protocol2
!= Protocol2End
)
2038 QualType D2Type
= Context
.ToCtx
.getObjCInterfaceType(D2
->getClassInterface());
2039 ObjCCategoryDecl::ivar_iterator Ivar2
= D2
->ivar_begin(),
2040 Ivar2End
= D2
->ivar_end();
2041 for (ObjCCategoryDecl::ivar_iterator Ivar1
= D1
->ivar_begin(),
2042 Ivar1End
= D1
->ivar_end();
2043 Ivar1
!= Ivar1End
; ++Ivar1
, ++Ivar2
) {
2044 if (Ivar2
== Ivar2End
)
2046 if (!IsStructurallyEquivalent(Context
, *Ivar1
, *Ivar2
, D2Type
))
2049 if (Ivar2
!= Ivar2End
)
2053 ObjCCategoryDecl::method_iterator Method2
= D2
->meth_begin(),
2054 Method2End
= D2
->meth_end();
2055 for (ObjCCategoryDecl::method_iterator Method1
= D1
->meth_begin(),
2056 Method1End
= D1
->meth_end();
2057 Method1
!= Method1End
; ++Method1
, ++Method2
) {
2058 if (Method2
== Method2End
)
2060 if (!IsStructurallyEquivalent(Context
, *Method1
, *Method2
))
2063 if (Method2
!= Method2End
)
2069 /// Determine structural equivalence of two declarations.
2070 static bool IsStructurallyEquivalent(StructuralEquivalenceContext
&Context
,
2071 Decl
*D1
, Decl
*D2
) {
2072 // FIXME: Check for known structural equivalences via a callback of some sort.
2074 D1
= D1
->getCanonicalDecl();
2075 D2
= D2
->getCanonicalDecl();
2076 std::pair
<Decl
*, Decl
*> P
{D1
, D2
};
2078 // Check whether we already know that these two declarations are not
2079 // structurally equivalent.
2080 if (Context
.NonEquivalentDecls
.count(P
))
2083 // Check if a check for these declarations is already pending.
2084 // If yes D1 and D2 will be checked later (from DeclsToCheck),
2085 // or these are already checked (and equivalent).
2086 bool Inserted
= Context
.VisitedDecls
.insert(P
).second
;
2090 Context
.DeclsToCheck
.push(P
);
2095 DiagnosticBuilder
StructuralEquivalenceContext::Diag1(SourceLocation Loc
,
2097 assert(Complain
&& "Not allowed to complain");
2099 FromCtx
.getDiagnostics().notePriorDiagnosticFrom(ToCtx
.getDiagnostics());
2100 LastDiagFromC2
= false;
2101 return FromCtx
.getDiagnostics().Report(Loc
, DiagID
);
2104 DiagnosticBuilder
StructuralEquivalenceContext::Diag2(SourceLocation Loc
,
2106 assert(Complain
&& "Not allowed to complain");
2107 if (!LastDiagFromC2
)
2108 ToCtx
.getDiagnostics().notePriorDiagnosticFrom(FromCtx
.getDiagnostics());
2109 LastDiagFromC2
= true;
2110 return ToCtx
.getDiagnostics().Report(Loc
, DiagID
);
2114 StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl
*Anon
) {
2115 ASTContext
&Context
= Anon
->getASTContext();
2116 QualType AnonTy
= Context
.getRecordType(Anon
);
2118 const auto *Owner
= dyn_cast
<RecordDecl
>(Anon
->getDeclContext());
2123 for (const auto *D
: Owner
->noload_decls()) {
2124 const auto *F
= dyn_cast
<FieldDecl
>(D
);
2128 if (F
->isAnonymousStructOrUnion()) {
2129 if (Context
.hasSameType(F
->getType(), AnonTy
))
2135 // If the field looks like this:
2136 // struct { ... } A;
2137 QualType FieldType
= F
->getType();
2138 // In case of nested structs.
2139 while (const auto *ElabType
= dyn_cast
<ElaboratedType
>(FieldType
))
2140 FieldType
= ElabType
->getNamedType();
2142 if (const auto *RecType
= dyn_cast
<RecordType
>(FieldType
)) {
2143 const RecordDecl
*RecDecl
= RecType
->getDecl();
2144 if (RecDecl
->getDeclContext() == Owner
&& !RecDecl
->getIdentifier()) {
2145 if (Context
.hasSameType(FieldType
, AnonTy
))
2156 unsigned StructuralEquivalenceContext::getApplicableDiagnostic(
2157 unsigned ErrorDiagnostic
) {
2158 if (ErrorOnTagTypeMismatch
)
2159 return ErrorDiagnostic
;
2161 switch (ErrorDiagnostic
) {
2162 case diag::err_odr_variable_type_inconsistent
:
2163 return diag::warn_odr_variable_type_inconsistent
;
2164 case diag::err_odr_variable_multiple_def
:
2165 return diag::warn_odr_variable_multiple_def
;
2166 case diag::err_odr_function_type_inconsistent
:
2167 return diag::warn_odr_function_type_inconsistent
;
2168 case diag::err_odr_tag_type_inconsistent
:
2169 return diag::warn_odr_tag_type_inconsistent
;
2170 case diag::err_odr_field_type_inconsistent
:
2171 return diag::warn_odr_field_type_inconsistent
;
2172 case diag::err_odr_ivar_type_inconsistent
:
2173 return diag::warn_odr_ivar_type_inconsistent
;
2174 case diag::err_odr_objc_superclass_inconsistent
:
2175 return diag::warn_odr_objc_superclass_inconsistent
;
2176 case diag::err_odr_objc_method_result_type_inconsistent
:
2177 return diag::warn_odr_objc_method_result_type_inconsistent
;
2178 case diag::err_odr_objc_method_num_params_inconsistent
:
2179 return diag::warn_odr_objc_method_num_params_inconsistent
;
2180 case diag::err_odr_objc_method_param_type_inconsistent
:
2181 return diag::warn_odr_objc_method_param_type_inconsistent
;
2182 case diag::err_odr_objc_method_variadic_inconsistent
:
2183 return diag::warn_odr_objc_method_variadic_inconsistent
;
2184 case diag::err_odr_objc_property_type_inconsistent
:
2185 return diag::warn_odr_objc_property_type_inconsistent
;
2186 case diag::err_odr_objc_property_impl_kind_inconsistent
:
2187 return diag::warn_odr_objc_property_impl_kind_inconsistent
;
2188 case diag::err_odr_objc_synthesize_ivar_inconsistent
:
2189 return diag::warn_odr_objc_synthesize_ivar_inconsistent
;
2190 case diag::err_odr_different_num_template_parameters
:
2191 return diag::warn_odr_different_num_template_parameters
;
2192 case diag::err_odr_different_template_parameter_kind
:
2193 return diag::warn_odr_different_template_parameter_kind
;
2194 case diag::err_odr_parameter_pack_non_pack
:
2195 return diag::warn_odr_parameter_pack_non_pack
;
2196 case diag::err_odr_non_type_parameter_type_inconsistent
:
2197 return diag::warn_odr_non_type_parameter_type_inconsistent
;
2199 llvm_unreachable("Diagnostic kind not handled in preceding switch");
2202 bool StructuralEquivalenceContext::IsEquivalent(Decl
*D1
, Decl
*D2
) {
2204 // Ensure that the implementation functions (all static functions in this TU)
2205 // never call the public ASTStructuralEquivalence::IsEquivalent() functions,
2206 // because that will wreak havoc the internal state (DeclsToCheck and
2207 // VisitedDecls members) and can cause faulty behaviour.
2208 // In other words: Do not start a graph search from a new node with the
2209 // internal data of another search in progress.
2210 // FIXME: Better encapsulation and separation of internal and public
2212 assert(DeclsToCheck
.empty());
2213 assert(VisitedDecls
.empty());
2215 if (!::IsStructurallyEquivalent(*this, D1
, D2
))
2221 bool StructuralEquivalenceContext::IsEquivalent(QualType T1
, QualType T2
) {
2222 assert(DeclsToCheck
.empty());
2223 assert(VisitedDecls
.empty());
2224 if (!::IsStructurallyEquivalent(*this, T1
, T2
))
2230 bool StructuralEquivalenceContext::IsEquivalent(Stmt
*S1
, Stmt
*S2
) {
2231 assert(DeclsToCheck
.empty());
2232 assert(VisitedDecls
.empty());
2233 if (!::IsStructurallyEquivalent(*this, S1
, S2
))
2239 bool StructuralEquivalenceContext::CheckCommonEquivalence(Decl
*D1
, Decl
*D2
) {
2240 // Check for equivalent described template.
2241 TemplateDecl
*Template1
= D1
->getDescribedTemplate();
2242 TemplateDecl
*Template2
= D2
->getDescribedTemplate();
2243 if ((Template1
!= nullptr) != (Template2
!= nullptr))
2245 if (Template1
&& !IsStructurallyEquivalent(*this, Template1
, Template2
))
2248 // FIXME: Move check for identifier names into this function.
2253 bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
2254 Decl
*D1
, Decl
*D2
) {
2257 if (D1
->getKind() != D2
->getKind())
2260 // Cast the Decls to their actual subclass so that the right overload of
2261 // IsStructurallyEquivalent is called.
2262 switch (D1
->getKind()) {
2263 #define ABSTRACT_DECL(DECL)
2264 #define DECL(DERIVED, BASE) \
2265 case Decl::Kind::DERIVED: \
2266 return ::IsStructurallyEquivalent(*this, static_cast<DERIVED##Decl *>(D1), \
2267 static_cast<DERIVED##Decl *>(D2));
2268 #include "clang/AST/DeclNodes.inc"
2273 bool StructuralEquivalenceContext::Finish() {
2274 while (!DeclsToCheck
.empty()) {
2275 // Check the next declaration.
2276 std::pair
<Decl
*, Decl
*> P
= DeclsToCheck
.front();
2280 Decl
*D2
= P
.second
;
2283 CheckCommonEquivalence(D1
, D2
) && CheckKindSpecificEquivalence(D1
, D2
);
2286 // Note that these two declarations are not equivalent (and we already
2288 NonEquivalentDecls
.insert(P
);