blob: eb60ed7b5b1dd1945d71ffb49112f5085e88649b [file] [log] [blame]
//===--- CGRecordLayoutBuilder.h - Record builder helper --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is a helper class used to build CGRecordLayout objects and LLVM types.
//
//===----------------------------------------------------------------------===//
#ifndef CLANG_CODEGEN_CGRECORDLAYOUTBUILDER_H
#define CLANG_CODEGEN_CGRECORDLAYOUTBUILDER_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/System/DataTypes.h"
#include <vector>
namespace llvm {
class Type;
}
namespace clang {
class ASTRecordLayout;
class CXXRecordDecl;
class FieldDecl;
class RecordDecl;
class QualType;
namespace CodeGen {
class CGRecordLayout;
class CodeGenTypes;
class CGRecordLayoutBuilder {
CodeGenTypes &Types;
/// Packed - Whether the resulting LLVM struct will be packed or not.
bool Packed;
/// ContainsPointerToDataMember - Whether one of the fields in this record
/// layout is a pointer to data member, or a struct that contains pointer to
/// data member.
bool ContainsPointerToDataMember;
/// Alignment - Contains the alignment of the RecordDecl.
unsigned Alignment;
/// AlignmentAsLLVMStruct - Will contain the maximum alignment of all the
/// LLVM types.
unsigned AlignmentAsLLVMStruct;
/// BitsAvailableInLastField - If a bit field spans only part of a LLVM field,
/// this will have the number of bits still available in the field.
char BitsAvailableInLastField;
/// NextFieldOffsetInBytes - Holds the next field offset in bytes.
uint64_t NextFieldOffsetInBytes;
/// FieldTypes - Holds the LLVM types that the struct is created from.
std::vector<const llvm::Type *> FieldTypes;
/// LLVMFieldInfo - Holds a field and its corresponding LLVM field number.
typedef std::pair<const FieldDecl *, unsigned> LLVMFieldInfo;
llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;
/// LLVMBitFieldInfo - Holds location and size information about a bit field.
struct LLVMBitFieldInfo {
LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start,
unsigned Size)
: FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { }
const FieldDecl *FD;
unsigned FieldNo;
unsigned Start;
unsigned Size;
};
llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;
CGRecordLayoutBuilder(CodeGenTypes &Types)
: Types(Types), Packed(false), ContainsPointerToDataMember(false)
, Alignment(0), AlignmentAsLLVMStruct(1)
, BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { }
/// Layout - Will layout a RecordDecl.
void Layout(const RecordDecl *D);
/// LayoutUnion - Will layout a union RecordDecl.
void LayoutUnion(const RecordDecl *D);
/// LayoutField - try to layout all fields in the record decl.
/// Returns false if the operation failed because the struct is not packed.
bool LayoutFields(const RecordDecl *D);
/// LayoutBases - layout the bases and vtable pointer of a record decl.
void LayoutBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout);
/// LayoutField - layout a single field. Returns false if the operation failed
/// because the current struct is not packed.
bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);
/// LayoutBitField - layout a single bit field.
void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset);
/// AppendField - Appends a field with the given offset and type.
void AppendField(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
/// AppendPadding - Appends enough padding bytes so that the total struct
/// size matches the alignment of the passed in type.
void AppendPadding(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
/// AppendPadding - Appends enough padding bytes so that the total
/// struct size is a multiple of the field alignment.
void AppendPadding(uint64_t FieldOffsetInBytes, unsigned FieldAlignment);
/// AppendBytes - Append a given number of bytes to the record.
void AppendBytes(uint64_t NumBytes);
/// AppendTailPadding - Append enough tail padding so that the type will have
/// the passed size.
void AppendTailPadding(uint64_t RecordSize);
unsigned getTypeAlignment(const llvm::Type *Ty) const;
uint64_t getTypeSizeInBytes(const llvm::Type *Ty) const;
/// CheckForPointerToDataMember - Check if the given type contains a pointer
/// to data member.
void CheckForPointerToDataMember(QualType T);
public:
/// ComputeLayout - Return the right record layout for a given record decl.
static CGRecordLayout *ComputeLayout(CodeGenTypes &Types,
const RecordDecl *D);
};
} // end namespace CodeGen
} // end namespace clang
#endif