blob: 022c8043d0a580400e93a0384371872b2dc65a5c [file] [log] [blame]
//===---- 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