comparison clang/lib/AST/CXXInheritance.cpp @ 207:2e18cbf3894f

LLVM12
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Jun 2021 06:07:14 +0900
parents 0572611fdcc8
children c4bab56944e8
comparison
equal deleted inserted replaced
173:0572611fdcc8 207:2e18cbf3894f
30 #include <utility> 30 #include <utility>
31 #include <cassert> 31 #include <cassert>
32 #include <vector> 32 #include <vector>
33 33
34 using namespace clang; 34 using namespace clang;
35
36 /// Computes the set of declarations referenced by these base
37 /// paths.
38 void CXXBasePaths::ComputeDeclsFound() {
39 assert(NumDeclsFound == 0 && !DeclsFound &&
40 "Already computed the set of declarations");
41
42 llvm::SmallSetVector<NamedDecl *, 8> Decls;
43 for (paths_iterator Path = begin(), PathEnd = end(); Path != PathEnd; ++Path)
44 Decls.insert(Path->Decls.front());
45
46 NumDeclsFound = Decls.size();
47 DeclsFound = std::make_unique<NamedDecl *[]>(NumDeclsFound);
48 std::copy(Decls.begin(), Decls.end(), DeclsFound.get());
49 }
50
51 CXXBasePaths::decl_range CXXBasePaths::found_decls() {
52 if (NumDeclsFound == 0)
53 ComputeDeclsFound();
54
55 return decl_range(decl_iterator(DeclsFound.get()),
56 decl_iterator(DeclsFound.get() + NumDeclsFound));
57 }
58 35
59 /// isAmbiguous - Determines whether the set of paths provided is 36 /// isAmbiguous - Determines whether the set of paths provided is
60 /// ambiguous, i.e., there are two or more paths that refer to 37 /// ambiguous, i.e., there are two or more paths that refer to
61 /// different base class subobjects of the same type. BaseType must be 38 /// different base class subobjects of the same type. BaseType must be
62 /// an unqualified, canonical class type. 39 /// an unqualified, canonical class type.
400 return Specifier->isVirtual() && 377 return Specifier->isVirtual() &&
401 Specifier->getType()->castAs<RecordType>()->getDecl() 378 Specifier->getType()->castAs<RecordType>()->getDecl()
402 ->getCanonicalDecl() == BaseRecord; 379 ->getCanonicalDecl() == BaseRecord;
403 } 380 }
404 381
405 bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier, 382 static bool isOrdinaryMember(const NamedDecl *ND) {
406 CXXBasePath &Path, 383 return ND->isInIdentifierNamespace(Decl::IDNS_Ordinary | Decl::IDNS_Tag |
407 DeclarationName Name) { 384 Decl::IDNS_Member);
408 RecordDecl *BaseRecord = 385 }
409 Specifier->getType()->castAs<RecordType>()->getDecl(); 386
410 387 static bool findOrdinaryMember(const CXXRecordDecl *RD, CXXBasePath &Path,
411 for (Path.Decls = BaseRecord->lookup(Name); 388 DeclarationName Name) {
412 !Path.Decls.empty(); 389 Path.Decls = RD->lookup(Name).begin();
413 Path.Decls = Path.Decls.slice(1)) { 390 for (DeclContext::lookup_iterator I = Path.Decls, E = I.end(); I != E; ++I)
414 if (Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag)) 391 if (isOrdinaryMember(*I))
415 return true; 392 return true;
416 }
417 393
418 return false; 394 return false;
419 } 395 }
420 396
421 static bool findOrdinaryMember(RecordDecl *BaseRecord, CXXBasePath &Path, 397 bool CXXRecordDecl::hasMemberName(DeclarationName Name) const {
422 DeclarationName Name) { 398 CXXBasePath P;
423 const unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | 399 if (findOrdinaryMember(this, P, Name))
424 Decl::IDNS_Member; 400 return true;
425 for (Path.Decls = BaseRecord->lookup(Name); 401
426 !Path.Decls.empty(); 402 CXXBasePaths Paths(false, false, false);
427 Path.Decls = Path.Decls.slice(1)) { 403 return lookupInBases(
428 if (Path.Decls.front()->isInIdentifierNamespace(IDNS)) 404 [Name](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
429 return true; 405 return findOrdinaryMember(Specifier->getType()->getAsCXXRecordDecl(),
430 } 406 Path, Name);
431 407 },
432 return false; 408 Paths);
433 } 409 }
434 410
435 bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, 411 static bool
436 CXXBasePath &Path, 412 findOrdinaryMemberInDependentClasses(const CXXBaseSpecifier *Specifier,
437 DeclarationName Name) { 413 CXXBasePath &Path, DeclarationName Name) {
438 RecordDecl *BaseRecord =
439 Specifier->getType()->castAs<RecordType>()->getDecl();
440 return findOrdinaryMember(BaseRecord, Path, Name);
441 }
442
443 bool CXXRecordDecl::FindOrdinaryMemberInDependentClasses(
444 const CXXBaseSpecifier *Specifier, CXXBasePath &Path,
445 DeclarationName Name) {
446 const TemplateSpecializationType *TST = 414 const TemplateSpecializationType *TST =
447 Specifier->getType()->getAs<TemplateSpecializationType>(); 415 Specifier->getType()->getAs<TemplateSpecializationType>();
448 if (!TST) { 416 if (!TST) {
449 auto *RT = Specifier->getType()->getAs<RecordType>(); 417 auto *RT = Specifier->getType()->getAs<RecordType>();
450 if (!RT) 418 if (!RT)
451 return false; 419 return false;
452 return findOrdinaryMember(RT->getDecl(), Path, Name); 420 return findOrdinaryMember(cast<CXXRecordDecl>(RT->getDecl()), Path, Name);
453 } 421 }
454 TemplateName TN = TST->getTemplateName(); 422 TemplateName TN = TST->getTemplateName();
455 const auto *TD = dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl()); 423 const auto *TD = dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
456 if (!TD) 424 if (!TD)
457 return false; 425 return false;
459 if (!RD) 427 if (!RD)
460 return false; 428 return false;
461 return findOrdinaryMember(RD, Path, Name); 429 return findOrdinaryMember(RD, Path, Name);
462 } 430 }
463 431
464 bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
465 CXXBasePath &Path,
466 DeclarationName Name) {
467 RecordDecl *BaseRecord =
468 Specifier->getType()->castAs<RecordType>()->getDecl();
469
470 for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty();
471 Path.Decls = Path.Decls.slice(1)) {
472 if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPReduction))
473 return true;
474 }
475
476 return false;
477 }
478
479 bool CXXRecordDecl::FindOMPMapperMember(const CXXBaseSpecifier *Specifier,
480 CXXBasePath &Path,
481 DeclarationName Name) {
482 RecordDecl *BaseRecord =
483 Specifier->getType()->castAs<RecordType>()->getDecl();
484
485 for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty();
486 Path.Decls = Path.Decls.slice(1)) {
487 if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPMapper))
488 return true;
489 }
490
491 return false;
492 }
493
494 bool CXXRecordDecl::
495 FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
496 CXXBasePath &Path,
497 DeclarationName Name) {
498 RecordDecl *BaseRecord =
499 Specifier->getType()->castAs<RecordType>()->getDecl();
500
501 for (Path.Decls = BaseRecord->lookup(Name);
502 !Path.Decls.empty();
503 Path.Decls = Path.Decls.slice(1)) {
504 // FIXME: Refactor the "is it a nested-name-specifier?" check
505 if (isa<TypedefNameDecl>(Path.Decls.front()) ||
506 Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag))
507 return true;
508 }
509
510 return false;
511 }
512
513 std::vector<const NamedDecl *> CXXRecordDecl::lookupDependentName( 432 std::vector<const NamedDecl *> CXXRecordDecl::lookupDependentName(
514 const DeclarationName &Name, 433 DeclarationName Name,
515 llvm::function_ref<bool(const NamedDecl *ND)> Filter) { 434 llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
516 std::vector<const NamedDecl *> Results; 435 std::vector<const NamedDecl *> Results;
517 // Lookup in the class. 436 // Lookup in the class.
518 DeclContext::lookup_result DirectResult = lookup(Name); 437 bool AnyOrdinaryMembers = false;
519 if (!DirectResult.empty()) { 438 for (const NamedDecl *ND : lookup(Name)) {
520 for (const NamedDecl *ND : DirectResult) { 439 if (isOrdinaryMember(ND))
521 if (Filter(ND)) 440 AnyOrdinaryMembers = true;
522 Results.push_back(ND); 441 if (Filter(ND))
523 } 442 Results.push_back(ND);
443 }
444 if (AnyOrdinaryMembers)
524 return Results; 445 return Results;
525 } 446
526 // Perform lookup into our base classes. 447 // Perform lookup into our base classes.
527 CXXBasePaths Paths; 448 CXXBasePaths Paths;
528 Paths.setOrigin(this); 449 Paths.setOrigin(this);
529 if (!lookupInBases( 450 if (!lookupInBases(
530 [&](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { 451 [&](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
531 return CXXRecordDecl::FindOrdinaryMemberInDependentClasses( 452 return findOrdinaryMemberInDependentClasses(Specifier, Path, Name);
532 Specifier, Path, Name);
533 }, 453 },
534 Paths, /*LookupInDependent=*/true)) 454 Paths, /*LookupInDependent=*/true))
535 return Results; 455 return Results;
536 for (const NamedDecl *ND : Paths.front().Decls) { 456 for (DeclContext::lookup_iterator I = Paths.front().Decls, E = I.end();
537 if (Filter(ND)) 457 I != E; ++I) {
538 Results.push_back(ND); 458 if (isOrdinaryMember(*I) && Filter(*I))
459 Results.push_back(*I);
539 } 460 }
540 return Results; 461 return Results;
541 } 462 }
542 463
543 void OverridingMethods::add(unsigned OverriddenSubobject, 464 void OverridingMethods::add(unsigned OverriddenSubobject,