blob: bca0b5c14290eb4c6af8c860f35d4402c2090ef5 [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;
Anders Carlssond5d64132009-07-28 17:56:36 +000046
47 /// NextFieldOffsetInBytes - Holds the next field offset in bytes.
48 uint64_t NextFieldOffsetInBytes;
Anders Carlsson307846f2009-07-23 03:17:50 +000049
50 /// FieldTypes - Holds the LLVM types that the struct is created from.
51 std::vector<const llvm::Type *> FieldTypes;
52
Anders Carlsson307846f2009-07-23 03:17:50 +000053 /// LLVMFieldInfo - Holds a field and its corresponding LLVM field number.
54 typedef std::pair<const FieldDecl *, unsigned> LLVMFieldInfo;
55 llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;
56
57 /// LLVMBitFieldInfo - Holds location and size information about a bit field.
58 struct LLVMBitFieldInfo {
Anders Carlsson8af896c2009-07-23 17:01:21 +000059 LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start,
60 unsigned Size)
61 : FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { }
Anders Carlsson307846f2009-07-23 03:17:50 +000062
63 const FieldDecl *FD;
64
Anders Carlsson8af896c2009-07-23 17:01:21 +000065 unsigned FieldNo;
Anders Carlsson307846f2009-07-23 03:17:50 +000066 unsigned Start;
67 unsigned Size;
68 };
69 llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;
70
71 CGRecordLayoutBuilder(CodeGenTypes &Types)
Anders Carlssond78fc892009-07-23 17:24:40 +000072 : Types(Types), Packed(false), AlignmentAsLLVMStruct(1)
Anders Carlssond5d64132009-07-28 17:56:36 +000073 , BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { }
Anders Carlsson307846f2009-07-23 03:17:50 +000074
75 /// Layout - Will layout a RecordDecl.
76 void Layout(const RecordDecl *D);
77
Anders Carlsson697f6592009-07-23 03:43:54 +000078 /// LayoutUnion - Will layout a union RecordDecl.
79 void LayoutUnion(const RecordDecl *D);
80
Anders Carlsson307846f2009-07-23 03:17:50 +000081 /// LayoutField - try to layout all fields in the record decl.
82 /// Returns false if the operation failed because the struct is not packed.
83 bool LayoutFields(const RecordDecl *D);
84
85 /// LayoutField - layout a single field. Returns false if the operation failed
86 /// because the current struct is not packed.
87 bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);
88
89 /// LayoutBitField - layout a single bit field.
90 void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset);
91
Anders Carlsson6e853bf2009-07-24 02:45:50 +000092 /// AppendField - Appends a field with the given offset and type.
93 void AppendField(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
Anders Carlsson307846f2009-07-23 03:17:50 +000094
95 /// AppendPadding - Appends enough padding bytes so that the total struct
96 /// size matches the alignment of the passed in type.
97 void AppendPadding(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
98
99 /// AppendPadding - Appends enough padding bytes so that the total
100 /// struct size is a multiple of the field alignment.
101 void AppendPadding(uint64_t FieldOffsetInBytes, unsigned FieldAlignment);
102
103 /// AppendBytes - Append a given number of bytes to the record.
104 void AppendBytes(uint64_t NumBytes);
105
Anders Carlssonb97a3ec2009-07-27 14:55:54 +0000106 /// AppendTailPadding - Append enough tail padding so that the type will have
107 /// the passed size.
108 void AppendTailPadding(uint64_t RecordSize);
109
Anders Carlsson307846f2009-07-23 03:17:50 +0000110 unsigned getTypeAlignment(const llvm::Type *Ty) const;
111 uint64_t getTypeSizeInBytes(const llvm::Type *Ty) const;
112
113public:
114 /// ComputeLayout - Return the right record layout for a given record decl.
115 static CGRecordLayout *ComputeLayout(CodeGenTypes &Types,
116 const RecordDecl *D);
117};
118
119} // end namespace CodeGen
120} // end namespace clang
121
122
123#endif