blob: 197e4206d3574598ec7945ed066d4ed4de4996f8 [file] [log] [blame]
Anders Carlsson307846f2009-07-23 03:17:50 +00001//===--- CGRecordLayoutBuilder.h - Record builder helper --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This is a helper class used to build CGRecordLayout objects and LLVM types.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef CLANG_CODEGEN_CGRECORDLAYOUTBUILDER_H
15#define CLANG_CODEGEN_CGRECORDLAYOUTBUILDER_H
16
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/Support/DataTypes.h"
19#include <vector>
20
21namespace llvm {
22 class Type;
23}
24
25namespace clang {
26 class FieldDecl;
27 class RecordDecl;
28
29namespace CodeGen {
30 class CGRecordLayout;
31 class CodeGenTypes;
32
33class CGRecordLayoutBuilder {
34 CodeGenTypes &Types;
35
Anders Carlssond78fc892009-07-23 17:24:40 +000036 /// Packed - Whether the resulting LLVM struct will be packed or not.
37 bool Packed;
Anders Carlsson307846f2009-07-23 03:17:50 +000038
39 /// AlignmentAsLLVMStruct - Will contain the maximum alignment of all the
40 /// LLVM types.
41 unsigned AlignmentAsLLVMStruct;
42
43 /// BitsAvailableInLastField - If a bit field spans only part of a LLVM field,
44 /// this will have the number of bits still available in the field.
45 char BitsAvailableInLastField;
46
47 /// FieldTypes - Holds the LLVM types that the struct is created from.
48 std::vector<const llvm::Type *> FieldTypes;
49
50 /// FieldInfo - Holds size and offset information about a field.
51 /// FIXME: I think we can get rid of this.
52 struct FieldInfo {
53 FieldInfo(uint64_t OffsetInBytes, uint64_t SizeInBytes)
54 : OffsetInBytes(OffsetInBytes), SizeInBytes(SizeInBytes) { }
55
56 const uint64_t OffsetInBytes;
57 const uint64_t SizeInBytes;
58 };
59 llvm::SmallVector<FieldInfo, 16> FieldInfos;
60
61 /// LLVMFieldInfo - Holds a field and its corresponding LLVM field number.
62 typedef std::pair<const FieldDecl *, unsigned> LLVMFieldInfo;
63 llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;
64
65 /// LLVMBitFieldInfo - Holds location and size information about a bit field.
66 struct LLVMBitFieldInfo {
Anders Carlsson8af896c2009-07-23 17:01:21 +000067 LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start,
68 unsigned Size)
69 : FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { }
Anders Carlsson307846f2009-07-23 03:17:50 +000070
71 const FieldDecl *FD;
72
Anders Carlsson8af896c2009-07-23 17:01:21 +000073 unsigned FieldNo;
Anders Carlsson307846f2009-07-23 03:17:50 +000074 unsigned Start;
75 unsigned Size;
76 };
77 llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;
78
79 CGRecordLayoutBuilder(CodeGenTypes &Types)
Anders Carlssond78fc892009-07-23 17:24:40 +000080 : Types(Types), Packed(false), AlignmentAsLLVMStruct(1)
Anders Carlsson307846f2009-07-23 03:17:50 +000081 , BitsAvailableInLastField(0) { }
82
83 /// Layout - Will layout a RecordDecl.
84 void Layout(const RecordDecl *D);
85
Anders Carlsson697f6592009-07-23 03:43:54 +000086 /// LayoutUnion - Will layout a union RecordDecl.
87 void LayoutUnion(const RecordDecl *D);
88
Anders Carlsson307846f2009-07-23 03:17:50 +000089 /// LayoutField - try to layout all fields in the record decl.
90 /// Returns false if the operation failed because the struct is not packed.
91 bool LayoutFields(const RecordDecl *D);
92
93 /// LayoutField - layout a single field. Returns false if the operation failed
94 /// because the current struct is not packed.
95 bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);
96
97 /// LayoutBitField - layout a single bit field.
98 void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset);
99
100 /// AppendField - Appends a field with the given offset size and type.
101 void AppendField(uint64_t FieldOffsetInBytes, uint64_t FieldSizeInBytes,
102 const llvm::Type *FieldTy);
103
104 /// AppendPadding - Appends enough padding bytes so that the total struct
105 /// size matches the alignment of the passed in type.
106 void AppendPadding(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
107
108 /// AppendPadding - Appends enough padding bytes so that the total
109 /// struct size is a multiple of the field alignment.
110 void AppendPadding(uint64_t FieldOffsetInBytes, unsigned FieldAlignment);
111
112 /// AppendBytes - Append a given number of bytes to the record.
113 void AppendBytes(uint64_t NumBytes);
114
115 /// getNextFieldOffsetInBytes - returns where the next field offset is.
116 uint64_t getNextFieldOffsetInBytes() const;
117
118 unsigned getTypeAlignment(const llvm::Type *Ty) const;
119 uint64_t getTypeSizeInBytes(const llvm::Type *Ty) const;
120
121public:
122 /// ComputeLayout - Return the right record layout for a given record decl.
123 static CGRecordLayout *ComputeLayout(CodeGenTypes &Types,
124 const RecordDecl *D);
125};
126
127} // end namespace CodeGen
128} // end namespace clang
129
130
131#endif