blob: 6890dbfc64321f21541a4cf8babb4f5fac2c2fc0 [file] [log] [blame]
Douglas Gregorbc0805a2008-10-23 00:40:37 +00001//===---- SemaInherit.cpp - C++ Inheritance ---------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file provides Sema routines for C++ inheritance semantics,
11// including searching the inheritance hierarchy and (eventually)
12// access checking.
13//
14//===----------------------------------------------------------------------===//
15
16#include "Sema.h"
17#include "clang/AST/ASTContext.h"
18#include "clang/AST/DeclCXX.h"
19
20namespace clang {
21
22/// IsDerivedFrom - Determine whether the class type Derived is
23/// derived from the class type Base, ignoring qualifiers on Base and
24/// Derived. This routine does not assess whether an actual conversion
25/// from a Derived* to a Base* is legal, because it does not account
26/// for ambiguous conversions or conversions to private/protected
27/// bases.
28bool Sema::IsDerivedFrom(QualType Derived, QualType Base)
29{
30 Derived = Context.getCanonicalType(Derived).getUnqualifiedType();
31 Base = Context.getCanonicalType(Base).getUnqualifiedType();
32
33 assert(Derived->isRecordType() && "IsDerivedFrom requires a class type");
34 assert(Base->isRecordType() && "IsDerivedFrom requires a class type");
35
36 if (Derived == Base)
37 return false;
38
39 if (const RecordType *DerivedType = Derived->getAsRecordType()) {
40 const CXXRecordDecl *Decl
41 = static_cast<const CXXRecordDecl *>(DerivedType->getDecl());
Douglas Gregor57c856b2008-10-23 18:13:27 +000042 for (CXXRecordDecl::base_class_const_iterator BaseSpec = Decl->bases_begin();
43 BaseSpec != Decl->bases_end(); ++BaseSpec) {
Douglas Gregorbc0805a2008-10-23 00:40:37 +000044 if (Context.getCanonicalType(BaseSpec->getType()) == Base
45 || IsDerivedFrom(BaseSpec->getType(), Base))
46 return true;
47 }
48 }
49
50 return false;
51}
52
53} // end namespace clang
54