aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaInherit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaInherit.cpp')
-rw-r--r--lib/Sema/SemaInherit.cpp54
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
+