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