@@ -513,42 +513,21 @@ void LookupResult::resolveKind() {
513
513
const NamedDecl *HasNonFunction = nullptr ;
514
514
515
515
llvm::SmallVector<const NamedDecl *, 4 > EquivalentNonFunctions;
516
- llvm::BitVector RemovedDecls (N);
517
516
518
- for (unsigned I = 0 ; I < N; I++) {
517
+ unsigned UniqueTagIndex = 0 ;
518
+
519
+ unsigned I = 0 ;
520
+ while (I < N) {
519
521
const NamedDecl *D = Decls[I]->getUnderlyingDecl ();
520
522
D = cast<NamedDecl>(D->getCanonicalDecl ());
521
523
522
524
// Ignore an invalid declaration unless it's the only one left.
523
525
// Also ignore HLSLBufferDecl which not have name conflict with other Decls.
524
- if ((D->isInvalidDecl () || isa<HLSLBufferDecl>(D)) &&
525
- N - RemovedDecls.count () > 1 ) {
526
- RemovedDecls.set (I);
526
+ if ((D->isInvalidDecl () || isa<HLSLBufferDecl>(D)) && !(I == 0 && N == 1 )) {
527
+ Decls[I] = Decls[--N];
527
528
continue ;
528
529
}
529
530
530
- // C++ [basic.scope.hiding]p2:
531
- // A class name or enumeration name can be hidden by the name of
532
- // an object, function, or enumerator declared in the same
533
- // scope. If a class or enumeration name and an object, function,
534
- // or enumerator are declared in the same scope (in any order)
535
- // with the same name, the class or enumeration name is hidden
536
- // wherever the object, function, or enumerator name is visible.
537
- if (HideTags && isa<TagDecl>(D)) {
538
- bool Hidden = false ;
539
- for (auto *OtherDecl : Decls) {
540
- if (canHideTag (OtherDecl) &&
541
- getContextForScopeMatching (OtherDecl)->Equals (
542
- getContextForScopeMatching (Decls[I]))) {
543
- RemovedDecls.set (I);
544
- Hidden = true ;
545
- break ;
546
- }
547
- }
548
- if (Hidden)
549
- continue ;
550
- }
551
-
552
531
std::optional<unsigned > ExistingI;
553
532
554
533
// Redeclarations of types via typedef can occur both within a scope
@@ -581,7 +560,7 @@ void LookupResult::resolveKind() {
581
560
if (isPreferredLookupResult (getSema (), getLookupKind (), Decls[I],
582
561
Decls[*ExistingI]))
583
562
Decls[*ExistingI] = Decls[I];
584
- RemovedDecls. set (I) ;
563
+ Decls[I] = Decls[--N] ;
585
564
continue ;
586
565
}
587
566
@@ -592,6 +571,7 @@ void LookupResult::resolveKind() {
592
571
} else if (isa<TagDecl>(D)) {
593
572
if (HasTag)
594
573
Ambiguous = true ;
574
+ UniqueTagIndex = I;
595
575
HasTag = true ;
596
576
} else if (isa<FunctionTemplateDecl>(D)) {
597
577
HasFunction = true ;
@@ -607,14 +587,36 @@ void LookupResult::resolveKind() {
607
587
if (getSema ().isEquivalentInternalLinkageDeclaration (HasNonFunction,
608
588
D)) {
609
589
EquivalentNonFunctions.push_back (D);
610
- RemovedDecls. set (I) ;
590
+ Decls[I] = Decls[--N] ;
611
591
continue ;
612
592
}
613
593
614
594
Ambiguous = true ;
615
595
}
616
596
HasNonFunction = D;
617
597
}
598
+ I++;
599
+ }
600
+
601
+ // C++ [basic.scope.hiding]p2:
602
+ // A class name or enumeration name can be hidden by the name of
603
+ // an object, function, or enumerator declared in the same
604
+ // scope. If a class or enumeration name and an object, function,
605
+ // or enumerator are declared in the same scope (in any order)
606
+ // with the same name, the class or enumeration name is hidden
607
+ // wherever the object, function, or enumerator name is visible.
608
+ // But it's still an error if there are distinct tag types found,
609
+ // even if they're not visible. (ref?)
610
+ if (N > 1 && HideTags && HasTag && !Ambiguous &&
611
+ (HasFunction || HasNonFunction || HasUnresolved)) {
612
+ const NamedDecl *OtherDecl = Decls[UniqueTagIndex ? 0 : N - 1 ];
613
+ if (isa<TagDecl>(Decls[UniqueTagIndex]->getUnderlyingDecl ()) &&
614
+ getContextForScopeMatching (Decls[UniqueTagIndex])->Equals (
615
+ getContextForScopeMatching (OtherDecl)) &&
616
+ canHideTag (OtherDecl))
617
+ Decls[UniqueTagIndex] = Decls[--N];
618
+ else
619
+ Ambiguous = true ;
618
620
}
619
621
620
622
// FIXME: This diagnostic should really be delayed until we're done with
@@ -623,15 +625,9 @@ void LookupResult::resolveKind() {
623
625
getSema ().diagnoseEquivalentInternalLinkageDeclarations (
624
626
getNameLoc (), HasNonFunction, EquivalentNonFunctions);
625
627
626
- // Remove decls by replacing them with decls from the end (which
627
- // means that we need to iterate from the end) and then truncating
628
- // to the new size.
629
- for (int I = RemovedDecls.find_last (); I >= 0 ; I = RemovedDecls.find_prev (I))
630
- Decls[I] = Decls[--N];
631
628
Decls.truncate (N);
632
629
633
- if ((HasNonFunction && (HasFunction || HasUnresolved)) ||
634
- (HideTags && HasTag && (HasFunction || HasNonFunction || HasUnresolved)))
630
+ if (HasNonFunction && (HasFunction || HasUnresolved))
635
631
Ambiguous = true ;
636
632
637
633
if (Ambiguous)
0 commit comments