diff options
Diffstat (limited to 'lib/Sema/SemaInherit.cpp')
-rw-r--r-- | lib/Sema/SemaInherit.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/Sema/SemaInherit.cpp b/lib/Sema/SemaInherit.cpp new file mode 100644 index 0000000000..022c8043d0 --- /dev/null +++ b/lib/Sema/SemaInherit.cpp @@ -0,0 +1,54 @@ +//===---- 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 + |