blob: ff551a4f135c2af732a70ab534679f0db133de4c [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
Anders Carlsson28a5fa22009-08-08 19:38:24 +000039 /// Alignment - Contains the alignment of the RecordDecl.
40 unsigned Alignment;
41
Anders Carlsson307846f2009-07-23 03:17:50 +000042 /// AlignmentAsLLVMStruct - Will contain the maximum alignment of all the
43 /// LLVM types.
44 unsigned AlignmentAsLLVMStruct;
45
46 /// BitsAvailableInLastField - If a bit field spans only part of a LLVM field,
47 /// this will have the number of bits still available in the field.
48 char BitsAvailableInLastField;
Anders Carlssond5d64132009-07-28 17:56:36 +000049
50 /// NextFieldOffsetInBytes - Holds the next field offset in bytes.
51 uint64_t NextFieldOffsetInBytes;
Anders Carlsson307846f2009-07-23 03:17:50 +000052
53 /// FieldTypes - Holds the LLVM types that the struct is created from.
54 std::vector<const llvm::Type *> FieldTypes;
55
Anders Carlsson307846f2009-07-23 03:17:50 +000056 /// LLVMFieldInfo - Holds a field and its corresponding LLVM field number.
57 typedef std::pair<const FieldDecl *, unsigned> LLVMFieldInfo;
58 llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;
59
60 /// LLVMBitFieldInfo - Holds location and size information about a bit field.
61 struct LLVMBitFieldInfo {
Anders Carlsson8af896c2009-07-23 17:01:21 +000062 LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start,
63 unsigned Size)
64 : FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { }
Anders Carlsson307846f2009-07-23 03:17:50 +000065
66 const FieldDecl *FD;
67
Anders Carlsson8af896c2009-07-23 17:01:21 +000068 unsigned FieldNo;
Anders Carlsson307846f2009-07-23 03:17:50 +000069 unsigned Start;
70 unsigned Size;
71 };
72 llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;
73
74 CGRecordLayoutBuilder(CodeGenTypes &Types)
Anders Carlsson28a5fa22009-08-08 19:38:24 +000075 : Types(Types), Packed(false), Alignment(0), AlignmentAsLLVMStruct(1)
Anders Carlssond5d64132009-07-28 17:56:36 +000076 , BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { }
Anders Carlsson307846f2009-07-23 03:17:50 +000077
78 /// Layout - Will layout a RecordDecl.
79 void Layout(const RecordDecl *D);
80
Anders Carlsson697f6592009-07-23 03:43:54 +000081 /// LayoutUnion - Will layout a union RecordDecl.
82 void LayoutUnion(const RecordDecl *D);
83
Anders Carlsson307846f2009-07-23 03:17:50 +000084 /// LayoutField - try to layout all fields in the record decl.
85 /// Returns false if the operation failed because the struct is not packed.
86 bool LayoutFields(const RecordDecl *D);
87
88 /// LayoutField - layout a single field. Returns false if the operation failed
89 /// because the current struct is not packed.
90 bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);
91
92 /// LayoutBitField - layout a single bit field.
93 void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset);
94
Anders Carlsson6e853bf2009-07-24 02:45:50 +000095 /// AppendField - Appends a field with the given offset and type.
96 void AppendField(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
Anders Carlsson307846f2009-07-23 03:17:50 +000097
98 /// AppendPadding - Appends enough padding bytes so that the total struct
99 /// size matches the alignment of the passed in type.
100 void AppendPadding(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
101
102 /// AppendPadding - Appends enough padding bytes so that the total
103 /// struct size is a multiple of the field alignment.
104 void AppendPadding(uint64_t FieldOffsetInBytes, unsigned FieldAlignment);
105
106 /// AppendBytes - Append a given number of bytes to the record.
107 void AppendBytes(uint64_t NumBytes);
108
Anders Carlssonb97a3ec2009-07-27 14:55:54 +0000109 /// AppendTailPadding - Append enough tail padding so that the type will have
110 /// the passed size.
111 void AppendTailPadding(uint64_t RecordSize);
112
Anders Carlsson307846f2009-07-23 03:17:50 +0000113 unsigned getTypeAlignment(const llvm::Type *Ty) const;
114 uint64_t getTypeSizeInBytes(const llvm::Type *Ty) const;
115
116public:
117 /// ComputeLayout - Return the right record layout for a given record decl.
118 static CGRecordLayout *ComputeLayout(CodeGenTypes &Types,
119 const RecordDecl *D);
120};
121
122} // end namespace CodeGen
123} // end namespace clang
124
125
126#endif