2008-10-23 08:40:37 +08:00
|
|
|
//===---- 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());
|
2008-10-24 02:13:27 +08:00
|
|
|
for (CXXRecordDecl::base_class_const_iterator BaseSpec = Decl->bases_begin();
|
|
|
|
BaseSpec != Decl->bases_end(); ++BaseSpec) {
|
2008-10-23 08:40:37 +08:00
|
|
|
if (Context.getCanonicalType(BaseSpec->getType()) == Base
|
|
|
|
|| IsDerivedFrom(BaseSpec->getType(), Base))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // end namespace clang
|
|
|
|
|