//===--- CGClass.cpp - Emit LLVM Code for C++ classes ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code dealing with C++ code generation of classes
//
//===----------------------------------------------------------------------===//
#include "CodeGenFunction.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/StmtCXX.h"
using namespace clang;
using namespace CodeGen;
static uint64_t
ComputeNonVirtualBaseClassOffset(ASTContext &Context,
const CXXRecordDecl *DerivedClass,
CXXBaseSpecifierArray::iterator Start,
CXXBaseSpecifierArray::iterator End) {
uint64_t Offset = 0;
const CXXRecordDecl *RD = DerivedClass;
for (CXXBaseSpecifierArray::iterator I = Start; I != End; ++I) {
const CXXBaseSpecifier *Base = *I;
assert(!Base->isVirtual() && "Should not see virtual bases here!");
// Get the layout.
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
const CXXRecordDecl *BaseDecl =
cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
// Add the offset.
Offset += Layout.getBaseClassOffset(BaseDecl);
RD = BaseDecl;
}
// FIXME: We should not use / 8 here.
return Offset / 8;
}
llvm::Constant *
CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
const CXXBaseSpecifierArray &BasePath) {
assert(!BasePath.empty() && "Base path should not be empty!");
uint64_t Offset =
ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl,
BasePath.begin(), BasePath.end());
if (!Offset)
return 0;
const llvm::Type *PtrDiffTy =
Types.ConvertType(getContext().getPointerDiffType());
return llvm::ConstantInt::get(PtrDiffTy, Offset);
}