diff options
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index b0b362f4cdb..2cc0d071a96 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1665,14 +1665,19 @@ void Sema::ActOnBaseSpecifiers(Decl *ClassDecl, CXXBaseSpecifier **Bases, /// \brief Determine whether the type \p Derived is a C++ class that is /// derived from the type \p Base. -bool Sema::IsDerivedFrom(QualType Derived, QualType Base) { +bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base) { if (!getLangOpts().CPlusPlus) return false; - + CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl(); if (!DerivedRD) return false; + // FIXME: In a modules build, do we need the entire path to be visible for us + // to be able to use the inheritance relationship? + if (RequireCompleteType(Loc, Derived, 0) && !DerivedRD->isBeingDefined()) + return false; + CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl(); if (!BaseRD) return false; @@ -1682,13 +1687,13 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base) { if (BaseRD->isInvalidDecl() || DerivedRD->isInvalidDecl()) return false; - // FIXME: instantiate DerivedRD if necessary. We need a PoI for this. - return DerivedRD->hasDefinition() && DerivedRD->isDerivedFrom(BaseRD); + return DerivedRD->isDerivedFrom(BaseRD); } /// \brief Determine whether the type \p Derived is a C++ class that is /// derived from the type \p Base. -bool Sema::IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths) { +bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base, + CXXBasePaths &Paths) { if (!getLangOpts().CPlusPlus) return false; @@ -1696,6 +1701,9 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths) { if (!DerivedRD) return false; + if (RequireCompleteType(Loc, Derived, 0) && !DerivedRD->isBeingDefined()) + return false; + CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl(); if (!BaseRD) return false; @@ -1747,7 +1755,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, // explore multiple paths to determine if there is an ambiguity. CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/false); - bool DerivationOkay = IsDerivedFrom(Derived, Base, Paths); + bool DerivationOkay = IsDerivedFrom(Loc, Derived, Base, Paths); assert(DerivationOkay && "Can only be used with a derived-to-base conversion"); (void)DerivationOkay; @@ -1781,7 +1789,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, // performance isn't as much of an issue. Paths.clear(); Paths.setRecordingPaths(true); - bool StillOkay = IsDerivedFrom(Derived, Base, Paths); + bool StillOkay = IsDerivedFrom(Loc, Derived, Base, Paths); assert(StillOkay && "Can only be used with a derived-to-base conversion"); (void)StillOkay; @@ -2757,7 +2765,8 @@ static bool FindBaseInitializer(Sema &SemaRef, // virtual base class. CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/false); - if (SemaRef.IsDerivedFrom(SemaRef.Context.getTypeDeclType(ClassDecl), + if (SemaRef.IsDerivedFrom(ClassDecl->getLocation(), + SemaRef.Context.getTypeDeclType(ClassDecl), BaseType, Paths)) { for (CXXBasePaths::paths_iterator Path = Paths.begin(); Path != Paths.end(); ++Path) { @@ -7123,7 +7132,7 @@ Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) { if (ConvType == ClassType) Diag(Conversion->getLocation(), diag::warn_conv_to_self_not_used) << ClassType; - else if (IsDerivedFrom(ClassType, ConvType)) + else if (IsDerivedFrom(Conversion->getLocation(), ClassType, ConvType)) Diag(Conversion->getLocation(), diag::warn_conv_to_base_not_used) << ClassType << ConvType; } else if (ConvType->isVoidType()) { @@ -13021,7 +13030,7 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New, if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) { // Check if the new class derives from the old class. - if (!IsDerivedFrom(NewClassTy, OldClassTy)) { + if (!IsDerivedFrom(New->getLocation(), NewClassTy, OldClassTy)) { Diag(New->getLocation(), diag::err_covariant_return_not_derived) << New->getDeclName() << NewTy << OldTy << New->getReturnTypeSourceRange(); |