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