@@ -2631,188 +2631,122 @@ bool Sema::isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS) {
2631
2631
return false;
2632
2632
}
2633
2633
2634
- /// Determine whether the given class is a base class of the given
2635
- /// class, including looking at dependent bases.
2636
- static bool findCircularInheritance(const CXXRecordDecl *Class,
2637
- const CXXRecordDecl *Current) {
2638
- SmallVector<const CXXRecordDecl*, 8> Queue;
2639
-
2640
- Class = Class->getCanonicalDecl();
2641
- while (true) {
2642
- for (const auto &I : Current->bases()) {
2643
- CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl();
2644
- if (!Base)
2645
- continue;
2646
-
2647
- Base = Base->getDefinition();
2648
- if (!Base)
2649
- continue;
2650
-
2651
- if (Base->getCanonicalDecl() == Class)
2652
- return true;
2653
-
2654
- Queue.push_back(Base);
2655
- }
2656
-
2657
- if (Queue.empty())
2658
- return false;
2659
-
2660
- Current = Queue.pop_back_val();
2661
- }
2662
-
2663
- return false;
2664
- }
2665
-
2666
2634
/// Check the validity of a C++ base class specifier.
2667
2635
///
2668
2636
/// \returns a new CXXBaseSpecifier if well-formed, emits diagnostics
2669
2637
/// and returns NULL otherwise.
2670
- CXXBaseSpecifier *
2671
- Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
2672
- SourceRange SpecifierRange,
2673
- bool Virtual, AccessSpecifier Access,
2674
- TypeSourceInfo *TInfo,
2675
- SourceLocation EllipsisLoc) {
2676
- // In HLSL, unspecified class access is public rather than private.
2677
- if (getLangOpts().HLSL && Class->getTagKind() == TagTypeKind::Class &&
2678
- Access == AS_none)
2679
- Access = AS_public;
2680
-
2638
+ CXXBaseSpecifier *Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
2639
+ SourceRange SpecifierRange,
2640
+ bool Virtual, AccessSpecifier Access,
2641
+ TypeSourceInfo *TInfo,
2642
+ SourceLocation EllipsisLoc) {
2681
2643
QualType BaseType = TInfo->getType();
2644
+ SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
2682
2645
if (BaseType->containsErrors()) {
2683
2646
// Already emitted a diagnostic when parsing the error type.
2684
2647
return nullptr;
2685
2648
}
2686
- // C++ [class.union]p1:
2687
- // A union shall not have base classes.
2688
- if (Class->isUnion()) {
2689
- Diag(Class->getLocation(), diag::err_base_clause_on_union)
2690
- << SpecifierRange;
2691
- return nullptr;
2692
- }
2693
2649
2694
- if (EllipsisLoc.isValid() &&
2695
- !TInfo->getType()->containsUnexpandedParameterPack()) {
2650
+ if (EllipsisLoc.isValid() && !BaseType->containsUnexpandedParameterPack()) {
2696
2651
Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
2697
2652
<< TInfo->getTypeLoc().getSourceRange();
2698
2653
EllipsisLoc = SourceLocation();
2699
2654
}
2700
2655
2701
- SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
2702
-
2703
- if (BaseType->isDependentType()) {
2704
- // Make sure that we don't have circular inheritance among our dependent
2705
- // bases. For non-dependent bases, the check for completeness below handles
2706
- // this.
2707
- if (CXXRecordDecl *BaseDecl = BaseType->getAsCXXRecordDecl()) {
2708
- if (BaseDecl->getCanonicalDecl() == Class->getCanonicalDecl() ||
2709
- ((BaseDecl = BaseDecl->getDefinition()) &&
2710
- findCircularInheritance(Class, BaseDecl))) {
2711
- Diag(BaseLoc, diag::err_circular_inheritance)
2712
- << BaseType << Context.getTypeDeclType(Class);
2713
-
2714
- if (BaseDecl->getCanonicalDecl() != Class->getCanonicalDecl())
2715
- Diag(BaseDecl->getLocation(), diag::note_previous_decl)
2716
- << BaseType;
2656
+ auto *BaseDecl =
2657
+ dyn_cast_if_present<CXXRecordDecl>(computeDeclContext(BaseType));
2658
+ // C++ [class.derived.general]p2:
2659
+ // A class-or-decltype shall denote a (possibly cv-qualified) class type
2660
+ // that is not an incompletely defined class; any cv-qualifiers are
2661
+ // ignored.
2662
+ if (BaseDecl) {
2663
+ // C++ [class.union.general]p4:
2664
+ // [...] A union shall not be used as a base class.
2665
+ if (BaseDecl->isUnion()) {
2666
+ Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
2667
+ return nullptr;
2668
+ }
2717
2669
2718
- return nullptr;
2670
+ // For the MS ABI, propagate DLL attributes to base class templates.
2671
+ if (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
2672
+ Context.getTargetInfo().getTriple().isPS()) {
2673
+ if (Attr *ClassAttr = getDLLAttr(Class)) {
2674
+ if (auto *BaseSpec =
2675
+ dyn_cast<ClassTemplateSpecializationDecl>(BaseDecl)) {
2676
+ propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseSpec,
2677
+ BaseLoc);
2678
+ }
2719
2679
}
2720
2680
}
2721
2681
2682
+ if (RequireCompleteType(BaseLoc, BaseType, diag::err_incomplete_base_class,
2683
+ SpecifierRange)) {
2684
+ Class->setInvalidDecl();
2685
+ return nullptr;
2686
+ }
2687
+
2688
+ BaseDecl = BaseDecl->getDefinition();
2689
+ assert(BaseDecl && "Base type is not incomplete, but has no definition");
2690
+
2691
+ // Microsoft docs say:
2692
+ // "If a base-class has a code_seg attribute, derived classes must have the
2693
+ // same attribute."
2694
+ const auto *BaseCSA = BaseDecl->getAttr<CodeSegAttr>();
2695
+ const auto *DerivedCSA = Class->getAttr<CodeSegAttr>();
2696
+ if ((DerivedCSA || BaseCSA) &&
2697
+ (!BaseCSA || !DerivedCSA ||
2698
+ BaseCSA->getName() != DerivedCSA->getName())) {
2699
+ Diag(Class->getLocation(), diag::err_mismatched_code_seg_base);
2700
+ Diag(BaseDecl->getLocation(), diag::note_base_class_specified_here)
2701
+ << BaseDecl;
2702
+ return nullptr;
2703
+ }
2704
+
2705
+ // A class which contains a flexible array member is not suitable for use as
2706
+ // a base class:
2707
+ // - If the layout determines that a base comes before another base,
2708
+ // the flexible array member would index into the subsequent base.
2709
+ // - If the layout determines that base comes before the derived class,
2710
+ // the flexible array member would index into the derived class.
2711
+ if (BaseDecl->hasFlexibleArrayMember()) {
2712
+ Diag(BaseLoc, diag::err_base_class_has_flexible_array_member)
2713
+ << BaseDecl->getDeclName();
2714
+ return nullptr;
2715
+ }
2716
+
2717
+ // C++ [class]p3:
2718
+ // If a class is marked final and it appears as a base-type-specifier in
2719
+ // base-clause, the program is ill-formed.
2720
+ if (FinalAttr *FA = BaseDecl->getAttr<FinalAttr>()) {
2721
+ Diag(BaseLoc, diag::err_class_marked_final_used_as_base)
2722
+ << BaseDecl->getDeclName() << FA->isSpelledAsSealed();
2723
+ Diag(BaseDecl->getLocation(), diag::note_entity_declared_at)
2724
+ << BaseDecl->getDeclName() << FA->getRange();
2725
+ return nullptr;
2726
+ }
2727
+
2728
+ // If the base class is invalid the derived class is as well.
2729
+ if (BaseDecl->isInvalidDecl())
2730
+ Class->setInvalidDecl();
2731
+ } else if (BaseType->isDependentType()) {
2722
2732
// Make sure that we don't make an ill-formed AST where the type of the
2723
2733
// Class is non-dependent and its attached base class specifier is an
2724
2734
// dependent type, which violates invariants in many clang code paths (e.g.
2725
2735
// constexpr evaluator). If this case happens (in errory-recovery mode), we
2726
2736
// explicitly mark the Class decl invalid. The diagnostic was already
2727
2737
// emitted.
2728
- if (!Class->getTypeForDecl()->isDependentType ())
2738
+ if (!Class->isDependentContext ())
2729
2739
Class->setInvalidDecl();
2730
- return new (Context) CXXBaseSpecifier(
2731
- SpecifierRange, Virtual, Class->getTagKind() == TagTypeKind::Class,
2732
- Access, TInfo, EllipsisLoc);
2733
- }
2734
-
2735
- // Base specifiers must be record types.
2736
- if (!BaseType->isRecordType()) {
2740
+ } else {
2741
+ // The base class is some non-dependent non-class type.
2737
2742
Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
2738
2743
return nullptr;
2739
2744
}
2740
2745
2741
- // C++ [class.union]p1:
2742
- // A union shall not be used as a base class.
2743
- if (BaseType->isUnionType()) {
2744
- Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
2745
- return nullptr;
2746
- }
2747
-
2748
- // For the MS ABI, propagate DLL attributes to base class templates.
2749
- if (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
2750
- Context.getTargetInfo().getTriple().isPS()) {
2751
- if (Attr *ClassAttr = getDLLAttr(Class)) {
2752
- if (auto *BaseTemplate = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2753
- BaseType->getAsCXXRecordDecl())) {
2754
- propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseTemplate,
2755
- BaseLoc);
2756
- }
2757
- }
2758
- }
2759
-
2760
- // C++ [class.derived]p2:
2761
- // The class-name in a base-specifier shall not be an incompletely
2762
- // defined class.
2763
- if (RequireCompleteType(BaseLoc, BaseType,
2764
- diag::err_incomplete_base_class, SpecifierRange)) {
2765
- Class->setInvalidDecl();
2766
- return nullptr;
2767
- }
2768
-
2769
- // If the base class is polymorphic or isn't empty, the new one is/isn't, too.
2770
- RecordDecl *BaseDecl = BaseType->castAs<RecordType>()->getDecl();
2771
- assert(BaseDecl && "Record type has no declaration");
2772
- BaseDecl = BaseDecl->getDefinition();
2773
- assert(BaseDecl && "Base type is not incomplete, but has no definition");
2774
- CXXRecordDecl *CXXBaseDecl = cast<CXXRecordDecl>(BaseDecl);
2775
- assert(CXXBaseDecl && "Base type is not a C++ type");
2776
-
2777
- // Microsoft docs say:
2778
- // "If a base-class has a code_seg attribute, derived classes must have the
2779
- // same attribute."
2780
- const auto *BaseCSA = CXXBaseDecl->getAttr<CodeSegAttr>();
2781
- const auto *DerivedCSA = Class->getAttr<CodeSegAttr>();
2782
- if ((DerivedCSA || BaseCSA) &&
2783
- (!BaseCSA || !DerivedCSA || BaseCSA->getName() != DerivedCSA->getName())) {
2784
- Diag(Class->getLocation(), diag::err_mismatched_code_seg_base);
2785
- Diag(CXXBaseDecl->getLocation(), diag::note_base_class_specified_here)
2786
- << CXXBaseDecl;
2787
- return nullptr;
2788
- }
2789
-
2790
- // A class which contains a flexible array member is not suitable for use as a
2791
- // base class:
2792
- // - If the layout determines that a base comes before another base,
2793
- // the flexible array member would index into the subsequent base.
2794
- // - If the layout determines that base comes before the derived class,
2795
- // the flexible array member would index into the derived class.
2796
- if (CXXBaseDecl->hasFlexibleArrayMember()) {
2797
- Diag(BaseLoc, diag::err_base_class_has_flexible_array_member)
2798
- << CXXBaseDecl->getDeclName();
2799
- return nullptr;
2800
- }
2801
-
2802
- // C++ [class]p3:
2803
- // If a class is marked final and it appears as a base-type-specifier in
2804
- // base-clause, the program is ill-formed.
2805
- if (FinalAttr *FA = CXXBaseDecl->getAttr<FinalAttr>()) {
2806
- Diag(BaseLoc, diag::err_class_marked_final_used_as_base)
2807
- << CXXBaseDecl->getDeclName()
2808
- << FA->isSpelledAsSealed();
2809
- Diag(CXXBaseDecl->getLocation(), diag::note_entity_declared_at)
2810
- << CXXBaseDecl->getDeclName() << FA->getRange();
2811
- return nullptr;
2812
- }
2813
-
2814
- if (BaseDecl->isInvalidDecl())
2815
- Class->setInvalidDecl();
2746
+ // In HLSL, unspecified class access is public rather than private.
2747
+ if (getLangOpts().HLSL && Class->getTagKind() == TagTypeKind::Class &&
2748
+ Access == AS_none)
2749
+ Access = AS_public;
2816
2750
2817
2751
// Create the base specifier.
2818
2752
return new (Context) CXXBaseSpecifier(
@@ -2857,13 +2791,20 @@ BaseResult Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange,
2857
2791
UPPC_BaseType))
2858
2792
return true;
2859
2793
2794
+ // C++ [class.union.general]p4:
2795
+ // [...] A union shall not have base classes.
2796
+ if (Class->isUnion()) {
2797
+ Diag(Class->getLocation(), diag::err_base_clause_on_union)
2798
+ << SpecifierRange;
2799
+ return true;
2800
+ }
2801
+
2860
2802
if (CXXBaseSpecifier *BaseSpec = CheckBaseSpecifier(Class, SpecifierRange,
2861
2803
Virtual, Access, TInfo,
2862
2804
EllipsisLoc))
2863
2805
return BaseSpec;
2864
- else
2865
- Class->setInvalidDecl();
2866
2806
2807
+ Class->setInvalidDecl();
2867
2808
return true;
2868
2809
}
2869
2810
0 commit comments