llvm-project/clang/lib/Sema/SemaInherit.cpp
Douglas Gregor 5c407d9a9b Add support for conversions from a pointer-to-derived to a
pointer-to-base. Also, add overload ranking for pointer conversions
(for both pointer-to-void and derived-to-base pointer conversions).

Note that we do not yet diagnose derived-to-base pointer conversion
errors that stem from ambiguous or inacessible base classes. These
aren't handled during overload resolution; rather, when the conversion
is actually used we go ahead and diagnose the error.

llvm-svn: 58017
2008-10-23 00:40:37 +00:00

55 lines
1.9 KiB
C++

//===---- SemaInherit.cpp - C++ Inheritance ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides Sema routines for C++ inheritance semantics,
// including searching the inheritance hierarchy and (eventually)
// access checking.
//
//===----------------------------------------------------------------------===//
#include "Sema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
namespace clang {
/// IsDerivedFrom - Determine whether the class type Derived is
/// derived from the class type Base, ignoring qualifiers on Base and
/// Derived. This routine does not assess whether an actual conversion
/// from a Derived* to a Base* is legal, because it does not account
/// for ambiguous conversions or conversions to private/protected
/// bases.
bool Sema::IsDerivedFrom(QualType Derived, QualType Base)
{
Derived = Context.getCanonicalType(Derived).getUnqualifiedType();
Base = Context.getCanonicalType(Base).getUnqualifiedType();
assert(Derived->isRecordType() && "IsDerivedFrom requires a class type");
assert(Base->isRecordType() && "IsDerivedFrom requires a class type");
if (Derived == Base)
return false;
if (const RecordType *DerivedType = Derived->getAsRecordType()) {
const CXXRecordDecl *Decl
= static_cast<const CXXRecordDecl *>(DerivedType->getDecl());
for (unsigned idx = 0; idx < Decl->getNumBases(); ++idx) {
const CXXBaseSpecifier *BaseSpec = Decl->getBase(idx);
if (Context.getCanonicalType(BaseSpec->getType()) == Base
|| IsDerivedFrom(BaseSpec->getType(), Base))
return true;
}
}
return false;
}
} // end namespace clang