2009-07-23 11:17:50 +08:00
|
|
|
//===--- 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/Support/DataTypes.h"
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
class Type;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
class FieldDecl;
|
|
|
|
class RecordDecl;
|
|
|
|
|
|
|
|
namespace CodeGen {
|
|
|
|
class CGRecordLayout;
|
|
|
|
class CodeGenTypes;
|
|
|
|
|
|
|
|
class CGRecordLayoutBuilder {
|
|
|
|
CodeGenTypes &Types;
|
|
|
|
|
2009-07-24 01:24:40 +08:00
|
|
|
/// Packed - Whether the resulting LLVM struct will be packed or not.
|
|
|
|
bool Packed;
|
2009-07-23 11:17:50 +08:00
|
|
|
|
2009-08-23 09:25:01 +08:00
|
|
|
/// ContainsMemberPointer - Whether one of the fields is a member pointer
|
|
|
|
/// or is a struct that contains a member pointer.
|
|
|
|
bool ContainsMemberPointer;
|
|
|
|
|
2009-08-09 03:38:24 +08:00
|
|
|
/// Alignment - Contains the alignment of the RecordDecl.
|
|
|
|
unsigned Alignment;
|
|
|
|
|
2009-07-23 11:17:50 +08:00
|
|
|
/// 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;
|
2009-07-29 01:56:36 +08:00
|
|
|
|
|
|
|
/// NextFieldOffsetInBytes - Holds the next field offset in bytes.
|
|
|
|
uint64_t NextFieldOffsetInBytes;
|
2009-07-23 11:17:50 +08:00
|
|
|
|
|
|
|
/// 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 {
|
2009-07-24 01:01:21 +08:00
|
|
|
LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start,
|
|
|
|
unsigned Size)
|
|
|
|
: FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { }
|
2009-07-23 11:17:50 +08:00
|
|
|
|
|
|
|
const FieldDecl *FD;
|
|
|
|
|
2009-07-24 01:01:21 +08:00
|
|
|
unsigned FieldNo;
|
2009-07-23 11:17:50 +08:00
|
|
|
unsigned Start;
|
|
|
|
unsigned Size;
|
|
|
|
};
|
|
|
|
llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;
|
|
|
|
|
|
|
|
CGRecordLayoutBuilder(CodeGenTypes &Types)
|
2009-08-23 09:25:01 +08:00
|
|
|
: Types(Types), Packed(false), ContainsMemberPointer(false)
|
|
|
|
, Alignment(0), AlignmentAsLLVMStruct(1)
|
2009-07-29 01:56:36 +08:00
|
|
|
, BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { }
|
2009-07-23 11:17:50 +08:00
|
|
|
|
|
|
|
/// Layout - Will layout a RecordDecl.
|
|
|
|
void Layout(const RecordDecl *D);
|
|
|
|
|
2009-07-23 11:43:54 +08:00
|
|
|
/// LayoutUnion - Will layout a union RecordDecl.
|
|
|
|
void LayoutUnion(const RecordDecl *D);
|
|
|
|
|
2009-07-23 11:17:50 +08:00
|
|
|
/// 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);
|
|
|
|
|
|
|
|
/// 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);
|
|
|
|
|
2009-07-24 10:45:50 +08:00
|
|
|
/// AppendField - Appends a field with the given offset and type.
|
|
|
|
void AppendField(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
|
2009-07-23 11:17:50 +08:00
|
|
|
|
|
|
|
/// 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);
|
|
|
|
|
2009-07-27 22:55:54 +08:00
|
|
|
/// AppendTailPadding - Append enough tail padding so that the type will have
|
|
|
|
/// the passed size.
|
|
|
|
void AppendTailPadding(uint64_t RecordSize);
|
|
|
|
|
2009-07-23 11:17:50 +08:00
|
|
|
unsigned getTypeAlignment(const llvm::Type *Ty) const;
|
|
|
|
uint64_t getTypeSizeInBytes(const llvm::Type *Ty) const;
|
|
|
|
|
2009-08-23 09:25:01 +08:00
|
|
|
/// CheckForMemberPointer - Check if the field contains a member pointer.
|
|
|
|
void CheckForMemberPointer(const FieldDecl *FD);
|
|
|
|
|
2009-07-23 11:17:50 +08:00
|
|
|
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
|